Some friends often ask DLL-related questions on the Forum. The following is a summary: 1. The DLL output function is called in the program and an illegal operation (stack error) occurs) This problem is generally caused by the inconsistency between the actual definition of the function and the declaration in use. To solve this problem, you must understand the function call mechanism. In Windows, there are two common calling methods: C and Pascal. C/C ++ uses the C method, that is, the parameter is pressed from right to left, and the caller is responsible for restoring the stack. The advantage of doing so is that the function with variable parameter numbers can be implemented, A typical example is scanf/printf. The other is Pascal, that is, the parameter is also pressed from right to left, but the function is responsible for Stack restoration, so that the caller does not care about the stack, saves coding costs (you do not need to add stack restoration commands to each function call ). In C/C ++, the default call method is C, also known as _ cdecl. To use Pascal, the description that must be displayed is Pascal (in VC, _ stdcall/PASCAL/winapi/callback is also available, which is actually a thing ). In fact, in DLL, the call method also affects the name of the function, which is not discussed yet, but is mentioned below. We can see the differences between C and Pascal through the assembly code (note that the line "**************" is added) Void function1 (DWORD V1, DWORD V2) { 10012560 push EBP 10012561 mov EBP, ESP 10012563 sub ESP, 0c0h 10012569 push EBX 1001256a push ESI 1001256b push EDI 1001256c Lea EDI, [ebp-0C0h] 10012572 mov ECx, 30 h 10012577 mov eax, 0 cccccccch 1001257c rep STOs dword ptr [EDI] } 1001257e pop EDI 1001257f pop ESI 10012580 pop EBX 10012581 mov ESP, EBP 10012583 pop EBP 10012584 RET //**************** Void winapi function2 (dword vi, DWORD V2) { 10012590 push EBP 10012591 mov EBP, ESP 10012593 sub ESP, 0c0h 10012599 push EBX 1001259a push ESI 1001259b push EDI 1001259c Lea EDI, [ebp-0C0h] 100125a2 mov ECx, 30 h 100125a7 mov eax, 0 cccccccch 100125ac rep STOs dword ptr [EDI] } 100125ae pop EDI 100125af pop ESI 100125b0 pop EBX 100125b1 mov ESP, EBP 100125b3 pop EBP 100125b4 RET 8 // *************** two DWORD parameters, eight bytes in total Function1 (1, 2 ); 10012604 push 2 // ********** C mode, from right to left into the stack 10012606 Push 1 10012608 call function1 (10011749 H) 1001260d add ESP, 8 // ********* the caller is responsible for replying to the stack Function2 (1, 2 ); 10012610 push 2 // ************* Pascal method, from right to left into the stack 10012612 Push 1 10012614 call function2 (1001_dfh) // The caller does not need to process the stack. 2. When DLL is dynamically loaded, the output function cannot be located using getprocaddress. There are two possible causes for this problem: one is that the function has no output at all, and the other is that the name of the output function is incorrect. These two reasons are caused by incorrect processing during DLL writing. Keywords related to DLL in VC include: _ declspec, dllexport, dllimport, extern "C ". Another point is the. Def definition file .. For the format of the def file, see related documentation. The following describes the DLL problems: A. _ declspec (export) only defines the output function B. extern "C" ensures that the output function is named as C, that is, the original function name is prefixed with an underscore (_). C. If you use. Def to define the output function, the output function is automatically named in the C format. In this case, the function definition does not include extern "c" and _ declspec (export) D. If the function uses the Pascal call style, use the. Def file to display the output. Otherwise, the name of the output function is incompatible with C (that is, the naming rules are different due to the call method mentioned above) E. the functions of _ declspec (dllexport) and _ declspec (dllimport) are the same. The former is usually used in the function definition (DLL, the latter is used in the referenced place (in the program ). 3. dll debugging Many of my friends want to debug the DLL while writing it. It is too troublesome to write a special debugging program. Using mydll. dll, funtest. This method is suitable for simple DLL debugging. 4. Cross-call between VC and BCB DLL Because VC and BCB use different lib file formats (Microsoft uses coff format, Borland uses OMF format), the two cannot directly cross-call the DLL file of the other party. To achieve the purpose of calling, you can only use the dynamic link method, that is, the loadlibrary/getprocaddress method, rather than the static Link Method for adding lib files, unless you find the software that can convert the coff format and the OMF format lib file (I haven't found it yet ). :-( |