Handling VB strings (as part of an array of UDT)
When using VC++ to create a DLL to be called from a Visual Basic program, there is a problem with passing data back and forth between the VB executable and the VC++ DLL. Specifically, when passing an array of User-Defined Type (UDT) from VB to VC++, if a data element of the UDT is a variable-length string, that element does not pass correctly. Instead of receiving a null-terminated string (as occurs when VB passes a regular string expression or an array of type String), the DLL receives a pointer to a data area which contains the sent string interspersed with nulls.
Thus, if you send the string "abc" as part of an array of UDT, your DLL function receives "a\0b\0c\0\0".
NOTE: This problem could be handled using Gert Rijs' article on "A class for double zeroterminated strings", but it would be awkward. The approach I took was to write a series of functions that makes handling these strings fairly easy.
Also note that since we're sending an array, it's necessary to use Microsoft's LPSAFEARRAY class to handle it. Finally, note that this code only works on Variable-length strings as part of an array of UDT being passed from VB: this code does not handle Fixed-length strings (I don't know how to handle Fixed-length).
The sample code includes a VB project and a VC++ project. The VB project creates an executable with which to test the DLL produced by the VC++ project. Note that you'll need to compile the VC++ code as a DLL, not as an executable, and you'll need to specify the "_stdcall" option under Project-Settings-C++ Code Generation.
This code compiles and runs under VB 5.0 and VC++ 5.0, respectively. Microsoft implemented LPSAFEARRAY as the method by which VB passes arrays to C++ DLL's with Version 5.0, so I strongly suspect the code will not run properly under earlier versions of either VB or VC++. It should work under 6.0, but I don't have the ability to test that.

Comments
VBA
Posted by tinapatel29 on 05/29/2006 04:37amHow to pass DLL To VBA(Visual Basic Application) DLL is of VC++. Pls explain with example
ReplyCalling a MATLAB generated Math DLL in VC++
Posted by Legacy on 02/18/2003 12:00amOriginally posted by: T.Madhu
I am having a function in MATLAB I have converted it to a c dll, using the mcc option of MATLAB I have created a ActiveX control and I am able to access all the functions in that dll my problem is how to pass the variable from VC++ to that dll bcoz all the variables in that dll are of type Variant, I am getting the error that cannot convert double to struct tag variant....
any body who can help me in this regard ....
Thanx in advance!
Madhu
ReplyProblem with boolean
Posted by Legacy on 01/24/2003 12:00amOriginally posted by: Rick
vb code:
Private Declare Function bd_get_integer _
Lib "bdb_api.dll" _
(ByVal tgid As String, _
ByVal tagid As String, _
ByRef value As Long, _
ByRef ecode As Long) As Boolean
Dim tgid As String
Dim tagid As String
tgid = Text1.Text
tagid = Text2.Text
Dim getint As Boolean
Dim value As Long
Dim ecode As Long
Dim TestTime, nTime, i, l
l = Timer
getint = bd_get_integer(tgid, tagid, value, ecode)
vc code:
bool __stdcall bd_get_integer (char* tgid, char* tag_id, long* value, long* ecode)
{
if (tgid == NULL) {
*ecode = 1;
return false;
}
if (tag_id == NULL) {
*ecode = 2;
return false;
}
:
:
:
}
I am getting a return value of true in VB. Can anyone help me??
ReplyHere is sample code passing string between VB and VC in DLL
Posted by Legacy on 11/05/2002 12:00amOriginally posted by: Onega
VB pass string to VC
Change the ByRef to ByVal in the Declare-statement. Sending it as a ByRef will send it as it is defined internally in VB. ByVal will send the actual string and not the internal struct (something like length + string).
Public Declare Sub DeReceiveStringFromVB Lib "ConnIris" ( _
ByVal s1 As String, ByVal s2 As String)
DeReceiveStringFromVB "aaa", "bbb"
__declspec( dllexport ) void __stdcall DeReceiveStringFromVB(LPCSTR lp1,LPCSTR lp2)
{
std::stringstream stmp;
stmp<<"ReceiveStringFromVB("<<lp1<<","<<lp2<<")";
OutputDebugString(stmp.str().c_str());
}
VC pass string to VB
__declspec( dllexport ) void __stdcall Long2String2(long lpdata,LPSTR pszString, LONG cSize)
{
wsprintf(pszString,"%d",lpdata);
}
Private Declare Sub Long2String2 Lib "vcvbdll" ( _
ByVal pFunc As Long, ByVal sMyString As String, ByVal cBufferSize As Long)
Dim sFillTest As String
ReplysFillTest = Space$(260)
Long2String2 wParam, sFillTest, 260
How to pass a VB Class to a C++ COM Dll
Posted by Legacy on 10/17/2002 12:00amOriginally posted by: Siddharth Barman
Hello,
I hope someone can help me with this.
I am trying to send a VB class (.CLS) object from a Vb program to a C++ COM Object. The VB class has a certain method which needs to be called by the C++ app. How can I do this?
I have managed to create the same thing using VB in the client as well as the Server. But, now, I require the server to be in C++.
When you pass an object like
Dim obj as New MyClient.MyClass
Dim myServerObj as new myServerObj.Serve
myServerObj.AddClient obj
thus I can have a callback mechanism from the server to the client.
I have been able to develop this fine when both client and server are in VB.
However in VC++, what should be the declaration of the AddClient function ?
should it be VARIANT? or LPDISPATCH? or what?
Also, how will a particular function of the client be called? In VB, all the server needs to do is:
obj.DoSomething <------- method defined by the client being called from the server
In VC++,
I am adding a class derived from CCmdTarget to get an automation class in my dialog based application.
I would appreciate any help from you.
Thanks,
ReplySid.
Summing up string passing between VB and VC
Posted by Legacy on 04/10/2002 12:00amOriginally posted by: Gregory
I recently created a DLL that imnplements shared mamory functionality to use in a vb project. VB is unbelievable regarding string (and many others..). Its default behaviour is using BSTRs when you decalre a variable as String.
1st observation
If your define a string inside a Type...EndType block, it passes it to the vc DLL as ANSI string.
2nd
I found out that it may be better to use the "Winapi aproach" when you want to return a string to a vb program. That means pass the buffer and the size of the buffer from the vb and use memcpy etc to copy the string.
E.g.
in VB
------
buff=String(vbNullChar,255) '!!! initialize (allocate space)
GetMyName(byval buff as String,size as Long)
in VC
------
void WINAPI GetMyName(LPSTR buff,long size)
{
memset(buff,...,size); // or even strcpy
}
Remember though to initialize the string or declare it in VB like that:
Declare String * 255
If you don't do that, you just pass a buffer to fill that is not allocated! That means a nice crash :)
ReplyNice But
Posted by Legacy on 03/10/2002 12:00amOriginally posted by: James
I want to extract properties of a control(MSHFlexGrid) Which is residing in other application .I have hooked control's thread by a dll.
ReplyI am getting all the properties of this contol if the application(In which control resides) is designed in vc++.
But I am not getting the properties if the application is in "VB"
Why is it so.
Please Help me
Regards,
James
Return string from VC to VB properly
Posted by Legacy on 08/10/2001 12:00amOriginally posted by: C Sluiter
ReplyI can't seem to get it to work.
Posted by Legacy on 09/11/1999 12:00amOriginally posted by: BoneHead
I've been trying to create my own DLL's to interact with VB. But no matter what I've done it doesn't seem to work. And now to my surprise, a demo project that is suppose to work comes up with the same error. "Can't find DLL entry point Test in dlldemo1.dll". I've been getting the same error for all of my trials. If anyone can't help, it would be appreciated.
Thanks.
ReplyHow use compiler option /Gz
Posted by Legacy on 09/09/1999 12:00amOriginally posted by: bind
i write a dll for vb ,use compiler option: /Gz,but can't link to other static library(eg: jpeg.lib)
ReplyWHY?
Loading, Please Wait ...