DLL call with __stdcall & GetProcAddress() in VS2013

后端 未结 1 1326
深忆病人
深忆病人 2020-12-10 21:55

I\'m trying to call a function from my own DLL, but depending on the calling convention in the DLL project either I can\'t find the ProcAddress or my stack is getting corrup

相关标签:
1条回答
  • 2020-12-10 22:50

    First, the calling convention used by the DLL function must match the function pointer definition you are using. Since it didn't match, you get the error that you've corrupted the stack.


    Second, When you use GetProcAddress the function name you use in the call to GetProcAddress must match exactly the exported DLL function name. It has to match not only on characters, but casing also i.e. myFunction is not the same as MyFunction.

    The exported name in your example is _myFunction@4. which means that accessing the function using GetProcAddress would be:

    GetProcAddress(myModuleHandle, "_myFunction@4");
    

    There is no getting around having to specify the name this way, since that is the name of the function.

    So you have two options:

    1. Change the code as described above, that is, to use the actual name or
    2. Change the DLL so that the exported name is actually myFunction

    Since we covered the first option, for the second option, you have to rebuild the DLL to use a Module Definition File (or simply known as a .DEF file) to redefine the name.

    Here is a link to what a module definition file is:

    Module Definition File

    So a typical .DEF file would contain this:

    LIBRARY MyDLL
    
    EXPORTS
        myFunction  @2   
    

    The @2 is the ordinal number. For your purposes, it is not important what this number is since there is only one function. I chose @2, but you can choose any number (@3, @4, or even @1000 if you desired). However, if there is more than 1 exported function, the ordinal numbers should be unique, i.e., you can't have two exported functions that have the same ordinal number.

    If you save the above contents to a MyDll.DEF and added it to the project that builds the DLL (not the project that will use the DLL), you will then need to rebuild the DLL. Once that's done, the DLL will now have an exported name of myFunction without the @4 decoration and without the underscore.

    (Note: As mentioned by the comment above, the extern "C" used does not turn off the decoration that Windows uses (the additional underscore and the @x appended to the name). All extern "C" does is turn off the C++ name mangling. To turn off the Windows name mangling, that requires the .DEF file.)

    P.S. I use a tool called Dependency Walker to easily determine what the exported function names are in a DLL. Since Dependency Walker is a GUI app, the output is a little friendlier than dumpbin.exe

    Dependency Walker

    Just to add, you mention that the DLL works flawlessly in other applications. If those other applications use import libraries instead of using LoadLibrary and GetProcAddress to access the function, then those import libraries automatically handle the translation of myFunction to _myFunction@4.

    That's why it works without issues for these types of applications. However, when you take the route of LoadLibrary and GetProcAddress, you are not afforded this "help" in getting the name translated, and you're basically on your own.

    0 讨论(0)
提交回复
热议问题