Note: Transfer from Yesky,
Original post address:
Http://soft.yesky.com/softchannel/72342371928637440/20040923/1857428.shtml
Author: pragmatic Time: 2004-09-23 Source: NEW YORK Editor: Ark
We often need to write some library functions or ActiveX controls yourself when writing Visual Basic applications, and these functions or controls often use VC languages, and thus different parameter types, memory between the two languages of VB and VC. Space usage is difficult, how to do it? This article describes the solution to these problems in the case of VB and VC hybrid programming. First, the custom type parameter is transferred to the DLL library function to mix programming, and the DLL library function written in VC is usually required in VB, which generally encounters the issue of passing parameters to library functions. For standard types (such as Double, Long, etc.) parameters, it is relatively simple, as long as it guarantees the declaration of the library function in VB and the definition of library functions in VC in the parameter type, order, and delivery mode, parameters Will not be passed by an error. However, if you need to pass the parameters of the custom type to the library function, the situation will become more complicated. Situation 1: All member variables of the custom type are the same type (for example, the following PENS custom type, which is a long type).
Type Pens Redpennum As Long Greenpennunnum As Long B1uepennum As LONGEND TYPE This time, as long as the structure is used in VB and VC , the structure is used in the same definition, and the VB and VC are fully notified (such as 32, bit operating system, InT and VB in VC , the difference in storage, no parameters are transmitted. Situation 2: The type of member variable in the custom type is incomplete. At this time, it is necessary to distinguish between two cases: Situation (1) There is no Double type member variable. At this time, it is generally not transmitted. The situation (2) contains a Double type member variable. The parameter is usually misused at this time. For example, the DLL library function of the following Person type parameters to VC , the value of the Double member Height is lost in the pass:
The reason why Typend Type causes the Height value is due to the storage of the Person type variable in VC , and the number of bytes will be automatically inserted between the LONG type member AGE and Double-type members Height, and VB is not meeting. Therefore, the memory required to store a Person type variable than 12 bytes in VC , while VB only needs 12. Therefore, the Person type variable that is incorporated from the VB to the DLL library function cannot be received correctly. There are many ways to solve this problem. Here is a relatively simple and general, called "introduction of the membership method": introducing several memory supplement members in the Person's custom type, so that The total number of bytes occupying the previous member of a Double type member is an integer multiple of the number of the number of Double Double variables (8). Still use the Person type as an example, because the AGE member occupies 4-byte memory, so you have to introduce a 4-byte replenishment member, you may introduce a String type member TEMPST:
TYPE PERSON AGE AS Long Tempst AS String * 4 Height As Doublend Type The total number of memory occupied by all members of the Double Member Height becomes 8 bytes, and is an integer multiple of 8. At this point, after the DLL library function is the same as the definition of Person, the Person type parameters from VB can be properly received correctly. Note: When introducing a member, it is necessary to rationally assign its occupy number of bytes, but also to correctly arrange the position in the structure, the two are not possible. In the above example, if the re-enabling member is placed in Height, the total number of bytes occupied by the Double Type Type Height is still 4, not an integer multiple of 8. When writing a DLL library function yourself, a complex custom structure is often used at the function interface. When this function is called in the VB, the "Introduction Additional Member Act" is used to appropriately modify the definition of the structure, and the error on the parameter delivery can be effectively avoided. Second, when using the memory mixing language programming of the dynamic application in VC , sometimes the memory is used in the VC dynamic application in the VB code. At this time, it can be implemented by the following method: 1) VC DLL library function char * APIENTRY CREATESTRINGBUFV; // Suppose needs to be applied to store dynamic memory BUF = Char *) :: Malloc (length); return buf; // Returns a string pointer, in fact, a long-type number} 2) VB receives a dynamic memory pointer code
... Declare Function CreateStringBuffer LIB "C: /DLLTEST/Test.dll" _ (by Val length As long) As long'long type change T receives dynamic memory pointer ... DIM SLBUFFER & AtBuffer = CreateStringBuffer 20) 'Apply a piece of memory that can store 20 characters, get pointers to the memory ...' Use this dynamic memory ... Note: After using the dynamic memory in VB, in order to avoid memory leakage Second, return its pointer to VC for memory release. Third, the custom type parameter is sent to the ActiveX control. When writing the VB program, if you use a standard ActiveX control, you generally don't need to pass the custom type parameters to the control, because most of the properties of most controls are standard types. Such as Double, Long). However, in the mixed language programming, when we use the ATL3.0 template (rather than VB) in VC , we often want to pass the parameters of the custom type to some attributes or methods to the control to enhance parameters. Transmission efficiency. Here is an easy way to pass a custom type parameter to the control. Suppose you want to develop an ActiveX control AX with VB, it has a Student property, the type is a custom structure Person:
TYPE PERSON AGE AS Long Height As Doublend Type first, correctly write interface functions for the Student property (develop AX using ATL3.0 template as an example). We write the interface parameter type of the Student property access function into a long-type pointer and is no longer BSTR. Because communication within ActiveX is all based on Unicode, so that this will avoid the parameters caused by the mismatch of the character set. The relevant code is as follows: 1) definition of the Student property in Ax.IDL
[Propget, ID (0), Helpstring ("Property Student")] HRESULTSTUDENT ([OUT, RETVAL] long * pval; [PropPut, ID (0), Helpstring ("Property Student")] HRESULTSTUDENT ([in] Long NEWVAL); 2) AX.H defines stdmethod (/ * [out, retval) (/ * [out, retval) (/ * [out, retval) (/ * [@] * / long newval ); 3) Implementation of the Student attribute access function in AXCPP
STDMETHODIMP CAX :: GET_STUDENT (long * pval) {// Todd: add your importation code here // Get the pointer to the member change T of the Student property, assignment * pvalreturn S_OK;} stdmethodimp cax :: put_student (long newval) { // Todd: add your importation code Here // Pointer to the residual resolution of the STUDENT property points to the memory space referred to in NewVal, // then copy the attribute value Return S_OK;} Second, correctly prepare the VB's Student property dynamically assignment code. In VB, first declare a Person type variable, after assigning the variable, obtain the memory address of the variable and assign it to the Student property. code show as below:
...... Dim StudentProp As PersonDim StudentAddr As LongStudentProp.Age = 23StudentProp.Heigth = 1.78 'obtained StudentProp variable memory address (Method omitted), assigned StudentAddrAX1.Student = StudentAddr ...... completion pointer means The custom type parameter is based on the transfer of the ActiveX control. The following facts: regardless of the control is .dll or .ocx, it is a server in one process with its customers. Therefore, as long as AX is compiled into .dll or .ocx, the passage of pointer is safe and reliable. Fourth, the determination of the length of the Chinese and English mixed string output length is often encountered in the VB programming, and can be effectively solved by VB, VC hybrid programming, which is given here. In the VB programming, you often need to get a certain length of the length you need to actually output. At this time, we usually consider two functions of Len () and lenb (). We know, LEN () returns the number of characters in the string, for a string that does not contain Chinese characters, the return value is usually equal to the output length of the string; the leNB () returns to the double byte The number of bytes occupied by the character set (DBCS), and the return value is usually equal to the output length of the string for a string composed of a pure Chinese character. However, when both Chinese, in English (see numbers such as English) characters, the return value of the two is not equal to the output length of the string. For example: "a Chinese" string, use the LEN () function to return 4; leNB () returns 8; when actually output (such as outputting the string to a log file), it will occupy 7 printing (1 each English character, 2 each Chinese characters). In order to calculate the output length of the Chinese-English mixed string, we can write a DLL library function that completes this calculated with VC , and calls the function directly in the VB. The call code in the VC function and the VB is as follows: 1) DLL functions in VC 6.0 long apientry sizeof_vbstring (char * at) {return (long) (:: atrlen (st)); // :: Atrlen () Return int Value, but under the 32-bit operating system, the INT type in // vc is quite equivalent to the range of the long type in VB. 2) VB 6.0 Declaration and call to sizeof_vbstring ()
... Declare Function SizeOf_vbstring lib "c: /dllteest.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 the pure English or pure Chinese string. (Finish)