Can I use the getprocaddress function to dynamically call the function in DLL? Must I use extern "c" to declare the export function? [Closed, closed by: darongtou]
For example, I searched for n more materials online and couldn't find a definite answer. Currently, my answer is "yes ". In the eveningProgram, I have studied it. In many documents, the output function can only be modified from C ++Code." However, it is not clear whether the call is explicit or implicit. I have never seen any code calling the export function without the extern "C" modifier through the display. On msdn The spelling and case of the function name pointed By lpprocname must be identical to that in Exports statement of the source DLL's module-Definition (. Def) file. The exported names of Win32 API functions May differ from the names you use when calling These functions in your code. The following is a theoretical analysis: The getprocaddress function declaration is: Farproc getprocaddress ( Hmodule, // handle to DLL module Lpstr lpprocname // name of Function ); C ++ supports function overloading. That is to say, multiple different functions can have the same function name. If it is not modified by extern "C", the same function name can be output. In this way, it is inconsistent with the getprocaddress function declaration. Therefore, it is inferred that the export function without the extern "C" modifier cannot be dynamically called, because the getprocaddress function uniquely identifies the address of the called function through the function name. Welcome to the discussion! 100 1st answers Show that the call must use the extern "C" modifier. Implicit call can use any type, but only C ++ can call an export function without the extern "C" modifier. Getprocaddress is a common API for getting function entry points and can be called in any language. Therefore, there must be many restrictions, for example, its parameter must be an ANSI string (the Unicode version is not provided in the operating system ).
2nd answers My understanding is as follows: getprocaddress is actually the same as calling myfunc () directly. It is used to query the export table to obtain the function address and then call it. Therefore, if you do not have a modifier, the entry cannot be found, no. Of course, I have never tried it and I am not sure of it.
3rd answers C Functions and C ++ functions have different names and can be viewed using tools, such as dependency Walker. If you want to test it, you can call getprocaddress Based on the name shown in the tool.
4th answers It is mainly about the name. There are two exceptions ": 1. If you do not use a C ++ compiler but use C to compile the DLL, the name will not change. You can not add extern "C" 2. If the DLL user knows that the DLL is compiled using the C ++ compiler, it does not add the extern "C", because he knows the rules for name change. Call getprocaddress and change the function name.
5th answers The C ++ compiler and C compiler generate different function names after compilation. Getprocaddress considers it a cdecl function, while The DLL is compiled by VC ++, so an extern "C" modifier must be added. Indicates that the function is generated as cdecl.
6th answers You can also find that you do not need to add extern "C". You only need to use the modified function name on the call end. You cannot use the original function name. The key code for the example is as follows: ---------------------------- DLL part: // This is an example of an exported function. Dll1_api int _ cdecl fndll1 (void) { Return 42; } The output modifier name is? Fndll1 @ yahxz Dll1_api int _ cdecl fndll1 (int) { Return 42 +; } The output modifier name is? Fndll1 @ Yahh @ Z ----------------------------- EXE part: Hinstance hmodule = loadlibrary ("dll1.dll "); Assert (hmodule ); Typedef int (* fndll1 )(); Fndll1 pfndll1 = NULL; // Verify (pfndll1 = (fndll1): getprocaddress (hmodule, "fndll1 ")); Verify (pfndll1 = (fndll1): getprocaddress (hmodule ,"? Fndll1 @ yahxz ")); Assert (pfndll1 () = 42 ); Typedef int (* fndll2) (INT ); Fndll2 pfndll2 = NULL; Verify (pfndll2 = (fndll2): getprocaddress (hmodule ,"? Fndll1 @ Yahh @ Z ")); Assert (pfndll2 (3) = 45 ); --------------------------- The experiment is the most powerful proof. |