When compiling Visual Basic applications, we often need to write some library functions or ActiveX controls by ourselves. These functions or controls are often written in the VC ++ language, therefore, it is often difficult for different parameter types and memory space usage methods between VB and VC. How can this problem be solved? This article describes how to solve these problems in the case of mixed programming of VB and VC.
1. Transmission of custom type parameters to dll library functions
When using VB, VC ++ for mixed programming, we usually need to call the dll library function compiled by VC ++ in VB. At this time, we usually encounter the problem of passing parameters to the library function. For standard parameters (such as double and long), the transfer is relatively simple, as long as the declaration of the library function in VB and the definition of the library function in VC ++ are consistent in the parameter type, order, and transmission mode, the parameter will not be transmitted incorrectly. However, if you need to pass a custom type parameter to the library function, the situation will become complicated.
Case 1: All member variables of the custom type are of the same type (for example, the following pens custom type has long members ).
Type pens
Redpennum as long
Greenpennum as long
B1uepennum as long
End type
In this case, we only need to use the same definition for the structure in VB and VC ++, and fully notice that VB and VC ++ have some data types (such as 32-bit operating systems, differences in the storage of int in VC ++ and integer in VB will not cause parameter passing errors.
Case 2: The member variables of the custom type are of different types. At this time, we need to distinguish between two situations:
Case (1) no double member variable.
In this case, the parameter transmission error is not displayed.
Case (2) contains double member variables.
In this case, parameters are usually mistakenly transmitted. For example, if the following person type parameter is passed to the dll library function developed by VC ++, the value of the height of the double type member will be lost in the transfer:
Type person
Age as long
Height as double
End type
The reason for the loss of the height value is that when the person variable is stored in VC ++, several bytes of separation space will be automatically inserted between the long member age and double member height, but VB does not. Therefore, to store a person variable in VC ++ requires more than 12 bytes of memory, while VB requires only 12 bytes. Therefore, the person-type variables that pass in dll library functions from VB cannot be correctly received.
There are many ways to solve this problem. Here we introduce a simple and universal method called "Introducing the complement Member method ": introduce several memory complement members in the custom type "person, so that the total number of bytes occupied by all members before a double member is an integer multiple of the number of bytes occupied by a single double variable (an integer multiple of 8 ).
Taking the person type as an example, because the age member occupies 4 bytes of memory, a 4-byte complement Member should be introduced later. You may wish to introduce a string-type member tempst:
Type person
Age as long
Tempst as string * 4
Height as double
End type
Therefore, the total memory occupied by all members before the double-type member height is changed to 8 bytes, which is an integer multiple of 8. In this case, after changing the person definition in the dll library function, you can correctly receive the person parameter from VB.
Note: When introducing a complement Member, you should not only reasonably allocate the number of bytes it occupies, but also arrange its position in the struct correctly. In the above example, if the complement Member is placed after the height, the total number of bytes occupied by all members before the height of the doubl variable is still 4, not an integer multiple of 8.
When writing dll library functions by yourself, complicated custom structures are often used at function interfaces. When calling such a function in VB, the structure definition can be appropriately modified using the "Introducing the complement Member method" to effectively avoid parameter transfer errors.
2. Use the dynamically applied memory in VC ++
For mixed language programming, you sometimes need to use the memory dynamically applied through VC ++ In the VB code. In this case, the following methods can be used:
1) dll library functions applied for dynamic memory in VC ++
Char * apientry createstringbuffer (long length)
{
Char * bufv; // assume that you need to apply for dynamic memory for storing the character Shen
Buf = (char *): malloc (length );
Return Buf; // returns a string pointer, which is actually a long number.
}
2) code for receiving dynamic memory pointers in VB
......
Declare function createstringbuffer lib "C:/dlltest/test. dll "_
(By Val length as long) as long
Note: Long variable t receives dynamic memory pointer
......
Dim slbuffer &
Atbuffer = createstringbuffer (20)
Note: Apply for a memory with 20 characters to get a pointer to the memory.
......
Note: use this dynamic memory
......
Note: After using dynamic memory in VB, to avoid Memory leakage, the pointer should be sent back to VC ++ for memory release.
Iii. Transmission of custom type parameters to ActiveX Controls
When compiling a VB program, if you use a standard ActiveX control, you do not need to pass custom parameters to the control, because most of the properties of the control are standard types (such as double, long. However, in mixed language programming, when we use the atl3.0 template in VC ++ instead of VB to develop ActiveX controls, you often want to pass custom parameters to certain properties or methods of the control to improve the transmission efficiency of parameters.
This section describes a simple way to pass custom type parameters to controls. Suppose we want to develop an ActiveX control ax using VB as the client. It has a student attribute and the type is custom structure person:
Type person
Age as long
Height as double
End type
First, write the interface functions of the student attribute correctly (using the atl3.0 template to develop ax as an example ). The interface parameter type of the student attribute access function is written as a long pointer instead of BSTR. Because all communication within ActiveX is based on Unicode, this process will avoid parameter mispassing due to Character Set mismatch. The related code is as follows:
1) definition of the student attribute in ax. IDL
[Propget, ID (0), helpstring ("Property student")] hresult
Student ([out, retval] Long * pval );
[Propput, ID (0), helpstring ("Property student")] hresult
Student ([in] Long newval );
2) definition of the student attribute access function in ax. h
Stdmethod (get_student) (/* [out, retval] */long * pval );
Stdmethod (put_student) (/* [in] */long newval );
3) Implementation of the student attribute access function in axcpp
Stdmethodimp CAX: get_student (long * pval)
{
// TODD: add your implementation code here
// Obtain the pointer for changing the member t storing the student attribute and assign it to * pval
Return s_ OK;
}
Stdmethodimp CAX: put_student (long newval)
{
// TODD: add your implementation code here
// Point the pointer to the address change of the member storing the student attribute to the memory space referred to by newval,
// Then copy the attribute values of student stored in this space through the memory copy method
Return s_ OK;
}
Second, correctly compile the code for dynamically assigning values to the student attribute of ax by VB. In VB, declare a person variable, assign a value to the variable, obtain the memory address of the variable, and assign it to the student attribute. The Code is as follows:
......
Dim studentprop as person
Dim studentaddr as long
Studentprop. Age = 23
Studentprop. heigth = 1.78
Note: Get the memory address of the studentprop variable (the method is omitted) and assign it to studentaddr.
Ax1.student = studentaddr
......
Using pointers to pass custom type parameters to ActiveX controls is based on the fact that, whether the control is. dll or. ocx, It is a server in the same process as its customers. Therefore, as long as ax is compiled into. dll or. ocx, pointer transmission is safe and reliable.
Iv. Determination of output length of Chinese and English mixed strings
The problem of determining the output length of Chinese and English mixed strings is often encountered in vbprogramming, and it can be effectively solved through VB, VC ++ hybrid programming.
In vbprogramming, you often need to obtain the length required by a string for actual output. At this time, we usually consider the Len () and lenb () functions.
We know that Len () returns the number of characters in the string. For a string without Chinese characters, the return value is usually equal to the output length of the string; lenb () the returned value is the number of bytes occupied by the string calculated based on the double-byte character set (DBCS). For a string composed of pure Chinese characters, the return value is usually equal to the output length of the string. However, when a string contains both Chinese and English characters (numbers are considered as English), the return values of both are not equal to the output length of the string. For example, if the string "A Chinese" is used, 4 is returned when Len () is used; If lenb () is used, 8 is returned; in actual output (for example, to output the string to a record file), it will occupy 7 prints (one for each English character and two for each Chinese character ).
In order to calculate the output length of the Chinese and English mixed strings, we can use VC ++ to compile a dll library function to complete this computation, and directly call this function in VB. The calling code of the VC ++ function and VB is as follows:
1) DLL Functions in VC ++ 6.0
Long apientry sizeof_vbstring (char *)
{
Return (long) (: atrlen (ST ));
//: Atrlen () returns the int value, but in a 32-bit operating system,
// The Int type in VC ++ is equivalent to the long type in VB.
}
2) Description and call of sizeof_vbstring () in VB 6.0
......
Declare function sizeof_vbstring lib "C:/dlltest. dll "_
(By Val st as string) as long
......
......
Dim stlen &
Stlen = sizeof_vbstring ("A Chinese ")
Stlen = 7
......
It should be noted that the above method can also calculate the input length of a string of pure English or Chinese characters.