Vb vc mixed programming troubleshooting
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 and 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 ).
TypePens
RedPenNumAsLong
GreenPenNumAsLong
B1uePenNumAsLong
EndType
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 and Integer in VB in VC 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 Double-type member Height will be lost during the transfer:
TypePerson
AgeAsLong
HeightAsDouble
EndType
The reason for the loss of the Height value is that when the Person variable is stored in VC, several bytes of separation space is automatically inserted between the Long and Double member Height, but VB does not. Therefore, VC requires more than 12 bytes of memory to store a Person variable, 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:
TypePerson
AgeAsLong
TempstAsString * 4
HeightAsDouble
EndType
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 the 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 * APIENTRYCreateStringBuffer (longLength)
{
Char * bufV; // assume that you need to apply for dynamic memory for storing the character Shen
Buf = (char *): malloc (Length );
Returnbuf; // returns a string pointer, which is actually a long number.
}
2) code for receiving dynamic memory pointers in VB
......
DeclareFunctionCreateStringBufferLib "C: DLLTestTest. dll "_
(ByValLengthAsLong) AsLong
'Long variable t receives dynamic memory pointer
......
DimslBuffer &
AtBuffer = CreateStringBuffer (20)
'Request a memory with 20 characters to get a pointer to the memory.
......
'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:
TypePerson
AgeAsLong
HeightAsDouble
EndType
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 ("propertyStudent")] HRESULT
Student ([out, retval] long * pVal );
[Propput, id (0), helpstring ("propertyStudent")] HRESULT
Student ([in] longnewVal );
2) definition of the Student attribute access function in AX. h
STDMETHOD (get_Student) (/* [out, retval] */long * pVal );
STDMETHOD (put_Student) (/* [in] */longnewVal );
3) Implementation of the Student attribute access function in AXcpp
STDMETHODIMPCAX: get_Student (long * pVal)
{
// TODD: Addyourimplementationcodehere
// Obtain the pointer for changing the member t storing the Student attribute and assign it to * pVal returnS_ OK;
}
STDMETHODIMPCAX: put_Student (longnewVal)
{
// TODD: Addyourimplementationcodehere
// 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
ReturnS_ 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:
......
DimStudentPropAsPerson
DimStudentAddrAsLong
StudentProp. Age = 23
StudentProp. Heigth = 1.78
'Obtain 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 can be effectively solved through VB and VC mixed programming, so it is provided here.
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 the 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
LongAPIENTRYSizeof_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 VB6.0
......
DeclareFunctionSizeof_vbStringLib "C: DLLTest. dll "_
(ByValstAsString) AsLong
......
......
DimstLen &
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.