When you use dependency to view the DLL export function name, you will find some interesting things, most of which are related to the export operator of the DLL export function specified during DLL compilation.
//////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////
When you use extern "C:
_ Stdcall will underline the name of the export function, followed by @ and the number of parameters. For example, _ fun @ 4 is four bytes.
_ Fastcall is similar to _ stdcall, but there is no underline in front. _ fastcall should have a @ in front, for example, @ loadadir @ 4
_ Cdecl is preceded by only an underscore
If extern "C" is not used, the C ++ naming mechanism is used, which involves C ++ name mangling. It is complicated and the compiler is not the same.
In addition, __declspec (dllexport) only processes _ cdecl and removes the preceding underline (for general global functions, the default value is _ cdecl ), but not for the other two.
//////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////
Extern "C" is used to prevent the "name destruction" feature of the C ++ compiler and enable the compiler to generate function names in the form of C, the actual function name in the C method is the same as that you wrote. If this is not available, the function name is generated in C ++ mode, so that the actual function name (the function name passed in by getprocaddress in loadlibrary mode) is different from the function name you have written, in this way, you cannot call the DLL using loadlibrary or getprocaddress.
However, the compiler automatically converts the function name by calling the function in the method of import (*. Lib), so there is always no problem.
//////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////
We know that to allow the DLL to export some functions, we need to add the identifier _ declspec (dllexport) before each function to be exported ). For example, you can export such a function (method) in a DLL)
# Define dll1_api _ declspec (dllexport)
Dllbench API int add (int A, int B)
{
Return A + B;
}
Now we can solve the name adaptation problem. When the C ++ compiler generates a DLL, it will modify the name of the exported function, and different compilers use different adaptation rules, therefore, the modified name is different. In this way, if different compilers are used to generate the DLL and the client accessing the DLL respectivelyProgramThe latter will cause problems when accessing the export function of the DLL. In the preceding example, what is the name after function add is adapted from the C ++ compiler? Add @ yahhh @ Z. We hope that the name after compilation will not change. Here are several methods.
The first is to add the qualifier: extern "C" when defining the export function"
# Define dll1_api extern "C" _ declspec (dllexport)
However, extern "C" only solves the problem of calling between C and C ++. It can only be used to export global functions, but cannot export member functions of a class. In addition, if the calling conventions of the exported function change, even if extern "C" is used, the compiled function name will change. For example, if we add the _ stdcall keyword, the call convention is the c call Convention (standard call Convention, that is, the winapi call Convention ).
# Define dll1_api extern "C" _ declspec (dllexport)
Dll1_api int _ stdcall add (int A, int B)
{
Return A + B;
}
After compilation, the function name Add is adapted to _ add @ 8.
The second method is to solve the problem through a module definition file def.
Library dllname
Exports
Add
Subtract
The library is used to specify the internal name of the dynamic link library. The name must match the generated Dynamic Link Library name.CodeNot required. Exports describes the functions to be exported by the DLL and the symbol names specified for these export functions.
The function name exported after the DLL is compiled using the module definition file method in the second method will not change.
//////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////
the traditional method for exporting DLL functions is to use the module definition file (. def), Visual C ++ provides a more concise and convenient method, that is, the keyword "_ declspec (dllexport)", for example:
__ declspec (dllexport) int _ stdcall myexportfunction (INT itest);
however, we can find that the name of the function exported by DLL is actually _ myexportfunction @ 4. Fortunately, VC provides a pre-processing indicator "# pragma" to specify the link option, which can be used to achieve our goal, as shown below:
# pragma comment (linker, "/export: myexportfunction = _ myexportfunction @ 4")
then, the exported function name becomes the desired myexportfunction.
Finally, we know that we should remove the _ declspec () modifier in front of the function. That is to say, we only need the second Pragma command. You can also use the following format:
# pragma comment (linker, "/export: myexportfunction = _ myexportfunction @ 4, private ")
the role of private is the same as that of Def files.