VB and other languages C DLL
DLL (DYNAMIC-LINK LIBRARY) is a file containing one or more functions / modules that are compiled, linked, and the process of calling it is separated.
Store. When the user process is started or running, the operating system is responsible for maping the DLL to the memory address space of the caller process. With DLL technology, you can improve software models
The reuse of the block (the DLL caller can not pay attention to the DLL written by the DLL) and the purpose of protecting the source code, while reducing the ultimately generated executable
The size of the file.
The DLL contains an export function table that contains the address within the DLL, but when the client is loaded into the DLL, I don't know the function address to be called, it is through
The symbolized name and serial number of the function are used to identify these functions. Simple program is usually an EXE import function from one or more DLL.
C / C has a low, high-level language characteristics, and there is another characteristic that other languages cannot replace, so the C / C language written DLL is handled some
It is especially important when the problem is. At the same time, due to the different compilers and other reasons, the compiler does not do too much work for cross-language calls.
Before discussing the C / C DLL in VB (PASCAL, FORTRAN, it is necessary to talk about the function call convention first.
CONVENTION and NAME Decoration.
1 function call convention (Function Calling Convention)
Function call conventions Determine how a program implements a function call and how the parameters are passed. In a single language
In the program, the call is almost always correct, because there is always a default agreement to all modules and the header file will be called and the called program
Containment. In a hybrid language program, different languages are impossible to share the same header file. Due to the incorrection resulting in the call, it cannot be found when compiling until
The program will appear when the function call is implemented and immediately causes the application to crash.
The calls supported by VC are as follows:
Keyword
Stack of maintainer
Parameter passing
__cdecl
Caller
Parameter reverse order (right-> left)
__stdcall
Caller
Parameter reverse order (right-> left)
__fastcall
Caller
Parameter first register, then enter the stack
ThisCall (not key)
Caller
Parameter, this pointer, ECX
Table 1 Call conventions supported by VC
We can also see the Fortran's call agreement and the similarities and differences of the C / C calls, as shown in the following table:
Calling convention
Parameter passing
Stack maintenance
C / C
Parameter reverse order (right-> left)
Caller
Fortran (__ stdcall)
Parameter reverse order (right-> left)
Caller
Table 2 CAU 2 C / C and Fortran call conventions
In C / C , you can specify a call agreement with a keyword __stdcall when a function declaration or definition. __stdcall call convention often in the Windows program
Or use in the API function. In the GUI program, both PASCAL, WINAPI, and Callback are defined as __stdcall. C language default calls agree to __cdecl.
2 name decoration (Name Decoration)
Name modification is a compiler that generates a unique string to identify the function when compiling function definitions or prototypes. C / C program internally
It is identified by the name after modification. When we specify a link to a function, we need a name modification. In most cases, we don't need the name of the function.
Modifications, linkers, or other tools are handled in a partner to match the function call. If you want to know the application of function name modifications, please refer to the documentation of the tool you use.
In VC, after we compile the source file containing a function definition or prototype, we can view the results of the function's name modification by one of the two methods.
1) Using compilation list
1 Use the compilation parameters (/ fa [c | s]) when compiling the source file containing a function declaration or prototype, set the compilation parameter to one of the following:
· Machine code, assembly (/ FAC)
· Source, Compilation (/ FAS)
· Machine code, source code, assembly (/ FACS)
2 Find the row in which the unmodified function definition is found in the result list.
3 Check the front line, the label of the proc near command is the name of the compiler.
2) Use dumpbin tools
Use the dumpbin command with / symbols parameter option to use the / symbol file, find the unmodified function definition in the output file (in a parentheses
Inner), before it is a function name modified by the compiler. The use of Dumpbin is as follows:
DUMPBIN LIBFILENAME / SYMBOLS / OUT: OUTFILENAME
For the following C function prototype:
Int Myfunc (int A, Double B)
Transform its call convention and connection specifier, observe the name modifications generated by the VC6.0 SP6 compiler, as follows:
------------
__cdecl
__fastcall
__stdcall
EXTERN "C"
_MYFUNC
_MYFUNC
@ Myfunc @ 12
_MYFUNC @ 12
------------
? Myfunc @@
Yahn @ z
? Myfunc @@
Yahn @ z
? Myfunc @@
Yihn @ z
? Myfunc @@
Yghhn @ z
Table 3 Relationship between name modifications and calls in C
3 VC and VB and other languages
In order to make the VB program (or written with PASCAL, FORTRAN language), these functions must be used in the correct number of functions in the C / C language.
Function call conventions, avoid any name modifications made by the compiler. In Windows 3.x and 16-bit version of C , you can use keywords
__pascal defines the export function. However, 32-bit version C no longer provides keywords __pascal. Alternatively, Pascal is used in Windef.h header files
Defined as __stdcall. In this way, the function call is agreed correctly (called function management stack and the parameter is transmitted from the right left, but generates a letter.
Number name modification. Therefore, when the function is exported from the C DLL from the C DLL, it is exported from the C DLL, not us.
The desired name (unmodified name, all letters).
Pascal name modification is a letter capital, unpaired name symbol. __stdcall name modification is to add a line before the name symbol (_), and then
Add "@" and function parameter bytes (required stack space). Therefore, the C function declaration as shown below:
INT __STDCALL FUNC (INT A, DOUBLE B);
Will be modified by the compiler:
_func @ 12
C call conventions (__cdecl) to modify the above function name as _func. However, the function name of the Pascal agreed should be func. In order to get the name of the modified, you can select General in the Category drop-down list in the Project / Settings tab of VC6.0, then select
Select the Generate MapFile check button. Select __Declspec (dllexport) to make the compiler work as follows:
• If the function is exported with a C call convention (__cdecl), the underscore (_) that is removed when the name is exported.
· If the function is not intended to be defined, (for example, using __stdcall), the modified name as described above is exported.
Therefore, in order to simulate the PASCAL name modification and function call conventions, the "called function management stack and parameters" provided by __stdcall must be used.
"And the name of the unmodified uppercase symbol.
We have to consider the stack maintenance and management, so __stdcall must be selected. At the same time, the symbol name exported by __stdcall conventions is in line with
Pascal agreed, you must use an alias to specify the sign name of the exported symbol name by the Expotrs field in the .def file. As follows:
Function declaration:
INT __STDCALL MyFunc (Int A, Double B);
Void __stdcall initcode (void);
In the .def file:
Exports
Myfunc = _MYFUNC @ 12
INITCODE = _INITCODE @ 0
For DLLs that will be called in the 32-bit application written in VB4.0, you need to use the alias method as shown in the .def file.
If you use an alias in the VB program, the specified alias in the .def file is no longer needed. In VB, you can use the following statement with the following statement with the alias keyword (DLL
The .def file no longer needs to use an alias):
Declare function myfunc lib "dllibname" alias "_myfunc @ 12" (...) AS Integer
Where DLLLBNAME is the name of the DLL file generated by the C compiler.
4 Pass the string to the DLL process
Typically, the string should be passed to the APIS using ByVal. Visual Basic uses a String data type called BSTR, which is a data type defined by automation (previously known as OLE Automation). A BSTR consists of a head and a string, and the header contains the length information of the string, and the string can contain an embedded NULL value. BSTR is transmitted in the form of a pointer, so the DLL process can modify the string. (The pointer is a variable, including the memory address of another variable, not data.) BSTR is Unicode, ie each character requires two bytes. BSTR usually ends with two bytes of NULL characters.
Most of the DLL (and all processes in the Window API) can identify the LPSTR type, which is a pointer to the standard NULL ended C language string, which is also referred to as an ASCIIZ string. LPSTR has no prefix. The figure below shows a LPSTR pointing to the ASCIIZ string.
If the DLL process requires a LPSTR (pointing to a pointer to the end of NULL) as a parameter, BSTR can be passed to it in use. Because the pointer to the BSTR actually points to the first data byte of the string ended with a null value, for the DLL process, it is a LPSTR.
Usually, if the DLL process requires a lpstr parameter, use the Byval keyword. If the DLL needs to get a pointer to the LPSTR, use the reference mode to pass the Visual Basic string. If you want to pass binary data to the DLL process, the variable can be passed as an array of Byte data types, and do not use it as a String variable. The string is assumed to contain characters, if binary data is passed as a String variable, the external program may not be able to read data correctly.
Assume that a string variable is declared, but does not initialize it, if it passes it to the DLL in use, the string variable will be passed as NULL instead of empty string (""). In order to eliminate confusion in the code, use the VBNullString constant if you want to pass NULL to the LPSTR parameter.
5 Pass the array to the DLL process
You can pass a single element in an array, the method is the same as the variable that is passed. When passing a single element, the element is transmitted as a substantially type variable.
Sometimes you need to pass the entire array to the DLL process. If the DLL process is specifically prepared for automation, the way the array passes to the DLL process is the same as that passed to the Visual Basic process: plus air parentheses. Because Visual Basic uses automated data types including SafeArray, DLL must be automated by Visual Basic array parameters. For further information, please refer to the specific DLL document.
If the DLL process cannot directly accept automation SafeArrays, the numerical array can still be passed throughout: The first unit of the array is passed in a reference mode. Because numeric arguments are always placed in memory, this approach is feasible. Just pass the first element of the array to the DLL process, the DLL can access all units of the array.
6 Pass the function pointer to DLL and type
Programmers who are familiar with C language will be familiar with the concept of function pointers. For readers who are not familiar with C language, it is necessary to explain this. Function pointer is an agreement, programmers can use it to pass the address of a custom function as a parameter to another. A function behind it may not be written, but has been declared, so you can use it in the application. With the function pointer, you can call the enumWindows and other functions list the window opened in the system, and all current fonts are listed using EnumFontFamilies. With the function pointer, you can access many other functions in the Win32 API, and early Visual Basic does not provide support for them.
In Visual Basic 5.0, there are still several restrictions when using a function pointer.
Use Addressof keyword
If the code wants to call the Visual Basic 5.0 function pointer, you must put the code in the standard .rable, you cannot put it in the class module, or it cannot be attached to the form. When using the AddressOf keyword declaration function, you must pay attention to the following:
Addressof can only be followed by parameters in the parameter list; this parameter can be a custom process, function, or name of the attribute.
The process, function, and attributes written behind Addressof must be in the same project in the same project.
Addressof can only be used for custom processes, functions, and properties that cannot be used for external functions declared by the DECLARE statement, nor can they be used for functions in the type library.
In the declared sub, function, or custom type definitions, the function pointer can be passed to the parameters of the AS ANY or AS LONG type.
Note that the callback function prototype in the DLL compiled with Visual C (or similar tools) can be created. When using addressof, the prototype must use the __stdcall call agreement. Cannot call the default call with addressof and store function pointers in variables
In some cases, it is necessary to store it in an intermediate variable before passing the function pointer to the DLL. This approach is useful if you need to pass the function pointer from a Visual Basic to another. For example, when you call a function such as RegisterClass, you need to transfer a function pointer with a member of the WNDCLASS.
To assign a function pointer to a member, you need to write a package function (Wrapper). For example, the FnpTrtolong created below is a packaging function that uses it to put a function pointer in any structure:
Function FnpTrtolong (Byval Lngfnptr As long) As long
FnpTrtolong = LNGFNPTR
END FUNCTION
To use this function, first you need to declare the type, then call FnPTRTOLONG. Addressof adds the name of the callback function as the parameter of the function.
DIM MT As mytype
Mt.myptr = fnptrtolong (addressof mycallbackfunction)
7 pass the custom data type to the DLL process
Some DLL processes use custom types as parameters. (In the C language, the custom type is called "structure", called "record" in Pascal.) Just as an array, if you want to pass a single member of the custom type, just use it as a general value Or string variables.
The entire custom type can be passed as a parameter, and a reference mode is required. Custom types cannot be passed in use. Visual Basic will pass the address of the first member and store other members in memory in the first one. There may be gaps between members on the operating system.
Customized members can be objects, arrays, and BSTR strings, although most of the DLL processes that accept custom types do not want to include string data in custom types. If the string member is a fixed length string, they will be equivalent to the string ended with empty characters, and the storage mode in memory is the same as other values. The variable length string in the custom type is actually a pointer to the string data. Each growing string member requires 4 bytes.
Note If you want to pass a custom type containing binary data to a DLL process, you need to store binary data in a variable array of Byte data types, and do not store it in a string variable. The string is assumed to store characters, if binary data is passed as String variables, the external process may read the result of the error.