|
-
April 20th, 2009, 05:30 AM
#1
Passing UDT from VB 6.0 to C++ DLL
From VB 6.0, I am invoking a API exported from C++ dll. The parameter of this function is a UDT containing string members. As an attempt to check the values, I printed the members of UDT as soon as the control enters into the C++ function and the values of the strings are garbage. Please let me know the steps to be followed to pass the parameters appropriately to the C++ function.
-
April 20th, 2009, 07:57 AM
#2
Re: Passing UDT from VB 6.0 to C++ DLL
Please show exactly how your UDT is defined.
The problem with strings passed to a C++ lib is:
C expects a pointer to the first character of the string.
VB's string type is a pointer not directly to the characters, but to a structure holding the length and the actual address of the characters (which are represented as 16bit values).
So if you have
Code:
Type myStrings
a as string
b as string
End Type
you are not passing pointers to characters.
Here you find some elaborations on that theme and surely a solution:
http://support.microsoft.com/kb/187912
Edit: As I recall just now, the pointer in the udt is apointer to a pointer to a string, like LPCSTR* a
So you just have to take that in account in your DLL.
Last edited by WoF; April 20th, 2009 at 08:18 AM.
-
April 20th, 2009, 10:11 AM
#3
Re: Passing UDT from VB 6.0 to C++ DLL
My UDT has 2 strings. A and B.
I am trying to convert the strings using strConv() with VBFromUnicode and store them into 2 Byte arrays. then i am copying those byte arrays into consecutive memory location (3rd byte array) using copymemory() and the resultant byte array is passed to the C++ dll.
still the problem is not resolved.
While converting the string to a byte array, i am using strconv() and pointer of the converted string is retrived using strptr(). The actual string is not getting copied after using copymemory().
how should I copy the string after converting into bytearray into the new location using copymemory? should it be using varptr or strptr?
-
April 20th, 2009, 12:27 PM
#4
Re: Passing UDT from VB 6.0 to C++ DLL
VB should take care converting the String to ANSI string. As an example, here's the testing you can use for the C++ dll
Code:
typedef struct {
char *a;
char *b;
}VB_UDT;
void WINAPI TestFunc(VB_UDT *pudt)
{
MessageBox(NULL, pudt->a, pudt->b, MB_ICONINFORMATION | MB_TASKMODAL);
}
And here's for the VB that calls the function
Code:
Private Type VB_UDT
a As String
b As String
End Type
Private Declare Sub TestFunc Lib "testdll.dll" (ByRef pudt As VB_UDT)
Private Sub Command1_Click()
Dim udt As VB_UDT
udt.a = "Text for the member a"
udt.b = "Text for the member b"
Call TestFunc(udt)
End Sub
Hope it will help you
-
April 20th, 2009, 03:13 PM
#5
Re: Passing UDT from VB 6.0 to C++ DLL
I have strings of fixed-length in both sides VB and C++. I fill the strings in VB without any problem. But it looks strange when printing the strings of UDT in C++.
Example:
I fill the strings A and B of UDT with values, A="first" and B="second".
I tried to print the values in C++ and the result is: A="first second" and B="second".
Even I tried to append the null char '\0' at the end of both strings in VB but the problem still persists in C++ side.
Please help me.
-
April 20th, 2009, 03:20 PM
#6
Re: Passing UDT from VB 6.0 to C++ DLL
Something else which may help is if you can use fixed-length strings. Then the UDT string members will be pointers to the string data directly.
Please remember to rate the posts and threads that you find useful.
How can something be both new and improved at the same time?
-
April 20th, 2009, 04:04 PM
#7
Re: Passing UDT from VB 6.0 to C++ DLL
Fixed-length string in UDT doesn't have the null terminator. Unlike C/C++, VB treats the whole length for storage. For example you have "a as String * 10" and you placed a of value "first", it will be passed to C as "first<space><space><space><space><space>" without a '\0' terminator.
What you can do in your C++ code is you can allocate a memory where you copy the content of the string + 1 more byte for the terminating character.
Code:
typedef struct {
char a[10];
char b[10];
}VB_UDT;
void WINAPI TestFunc(VB_UDT *pudt)
{
char *a = new char[sizeof(pudt->a) + 1];
memcpy(a, pudt->a, sizeof(pudt->a));
a[sizeof(pudt->a)] = '\0';
char *b = new char[sizeof(pudt->b) + 1];
memcpy(b, pudt->b, sizeof(pudt->b));
b[sizeof(pudt->b)] = '\0';
MessageBox(NULL, a, b, MB_ICONINFORMATION | MB_TASKMODAL);
delete[] a;
delete[] b;
}
Or you can make the size of the string in VB more enough to hold the string plus a Chr(0)
Code:
Private Type VB_UDT
a As String * 10
b As String * 10
End Type
...
Dim udt As VB_UDT
udt.a = "first" & Chr(0)
udt.b = "second" & Chr(0)
Just take note that you should always add Chr(0) so that C/C++ can read it correctly. The actual string plus the Chr(0) should also be less than or equal to the size of the fixed length string.
The easiest way is to use a variable length string as in my example.
Last edited by rxbagain; April 20th, 2009 at 04:07 PM.
-
April 20th, 2009, 04:29 PM
#8
Re: Passing UDT from VB 6.0 to C++ DLL
The second choice, appending null char in VB end is suitable for my application and it works now.
Thanks very much for all your help :-D
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|