passing (string) arrays from VB to C-DLL and vice versa
Author |
Message |
Julia #1 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
hi, i have a VB application and a C DLL and i have been going crazy the past week trying to send string arrays back and forth !!! can someone pls help me out ? or atleast point me to some good website which explains clearly how to go abt this? i searched the web but cudn't get a clear idea of what they were trying to say. i need my DLL to return an array of strings which VB can read properly. is that possible?? thanks, Julian.
|
Tue, 11 Jan 2005 04:16:31 GMT |
|
 |
Frank Ad #2 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
Quote:
>hi, > i have a VB application and a C DLL and i have been going crazy the past >week trying to send string arrays back and forth !!! >can someone pls help me out ? or atleast point me to some good website which >explains clearly how to go abt this? >i searched the web but cudn't get a clear idea of what they were trying to >say. >i need my DLL to return an array of strings which VB can read properly. is >that possible??
I've never got this to work too well either, or not to my liking anyway. You do however have to return a BSTR allocated with SysAllocString. Otherwise when your function exits, the pointer you've returned is probably thrashed, by thetime VB gets to it.. kinda like this pseudo.. build the strings, whatever.. add up the size of all strings on the way (+1 for each delimiter) Use SysAlocStringLen to init the BSTR the real crappy bit starts here... sprintf the first element into the BSTR, cast as required. strcat a '\r" on it, again casting the BSTR to a char* is required. for i = 1 to stringcount strcat to BSTR, element[i] strcat to BSTR, "\r" return bstr; On the VB end declare function blabla lib "whatver.dll" () As String 'single string! So in the calling function you would have something like this dim sRet as Variant sRet = Split(blabla(), chr$(10)) That's about it. It's dirty, looks horrible, but it worked once. I'll certainly be keeping my ear on this thread though for a better way. :) Come to think, i've never tried to create a BSTR array... hmmmm If that's possible, it could be used directly with SysAllocString.. Will try later maybe.. or even better, let us know if you do. :) Regards, Frank
|
Tue, 11 Jan 2005 13:09:45 GMT |
|
 |
Doug Ros #3 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
...then on top of all that, VB can only call standard functions exported using stdcall. Name mangling may be a problem too. And then can VB even deal with exported standard C++ classes? I'm pretty sure this is impossible (or more pain than it's worth) and any object oriented stuff must be done in COM. I've never done it though...
Quote: > I've never got this to work too well either, or not to my liking > anyway. You do however have to return a BSTR allocated with > SysAllocString. Otherwise when your function exits, the pointer you've > returned is probably thrashed, by thetime VB gets to it..
<snip>
|
Tue, 11 Jan 2005 19:13:41 GMT |
|
 |
Frank Ad #4 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
Quote:
>...then on top of all that, VB can only call standard functions exported >using stdcall. Name mangling may be a problem too. And then can VB even >deal with exported standard C++ classes? I'm pretty sure this is impossible
I've managed to export functions out of a class, but i could never export a complete class to VB. Even though i remember reading up on various docs which suggested that it can be done. Of course that is not much use, might as well have a C DLL. Quote: >(or more pain than it's worth) and any object oriented stuff must be done in >COM. I've never done it though...
I'll try again just after i've retired i think. :) Same with ATL COMs, well maybe not, that i should really look into one day soon before VB starts tripping over accidently .Netivated Windows controls. :-) Regards, Frank
|
Tue, 11 Jan 2005 20:37:15 GMT |
|
 |
Doug Ros #5 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
Quote:
> >...then on top of all that, VB can only call standard functions exported > >using stdcall. Name mangling may be a problem too. And then can VB even > >deal with exported standard C++ classes? I'm pretty sure this is impossible > I've managed to export functions out of a class, but i could never > export a complete class to VB. Even though i remember reading up on > various docs which suggested that it can be done. Of course that is > not much use, might as well have a C DLL.
That's what I was thinking... Quote: > >(or more pain than it's worth) and any object oriented stuff must be done in > >COM. I've never done it though... > I'll try again just after i've retired i think. :) > Same with ATL COMs, well maybe not, that i should really look into one > day soon before VB starts tripping over accidently .Netivated Windows > controls. :-)
I don't even know *what* to look into any more. {*filter*}y M$ keeps changing things. All they do is create needless work for people, and the people they are saving work for are just going to get the same treatment in a few years... Heh, you think that .netivation of anything is accidental? :) They'd .netivate your dead grandmother if they could...
|
Wed, 12 Jan 2005 00:32:28 GMT |
|
 |
Doug Ros #6 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
Oh, and don't multipost.
|
Wed, 12 Jan 2005 00:32:31 GMT |
|
 |
Frank Ad #7 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
Quote:
>I don't even know *what* to look into any more. {*filter*}y M$ keeps changing >things. All they do is create needless work for people, and the people they >are saving work for are just going to get the same treatment in a few years...
^^^^^^^^ Psychiatric or hair replacement ? :-) Quote: > Heh, you think that .netivation of anything is accidental? :) >They'd .netivate your dead grandmother if they could...
Maybe i'll start using :-x for sarcastix <sic>. ;-) Btw, i don't see multiposting in the OP's header ? Then again i don't see much, it's 3 AM. Regards, Frank
|
Wed, 12 Jan 2005 01:13:43 GMT |
|
 |
Julia #8 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
actually, what you have mentioned was my back-up plan. and i already have working code for that idea - using a *single* delimited string. but what i was looking for was an array of strings. that means i have to really understand SAFEARRAYs for it to work. and that is what i am not able to do. does someone have a working code which creates a SAFEARRAY (of any type) on the C side and returns it to VB ? and i'm sorry abt the multiposting. i guess i'm not familiar with the newsgroup etiquette. but just out of curiosity, why is multi-posting a big no-no?? wudn't it help me reach a bigger audience?? thanks, Julian.
Quote:
> >hi, > > i have a VB application and a C DLL and i have been going crazy the past > >week trying to send string arrays back and forth !!! > >can someone pls help me out ? or atleast point me to some good website which > >explains clearly how to go abt this? > >i searched the web but cudn't get a clear idea of what they were trying to > >say. > >i need my DLL to return an array of strings which VB can read properly. is > >that possible?? > I've never got this to work too well either, or not to my liking > anyway. You do however have to return a BSTR allocated with > SysAllocString. Otherwise when your function exits, the pointer you've > returned is probably thrashed, by thetime VB gets to it.. > kinda like this pseudo.. > build the strings, whatever.. > add up the size of all strings on the way (+1 for each delimiter) > Use SysAlocStringLen to init the BSTR > the real crappy bit starts here... > sprintf the first element into the BSTR, cast as required. > strcat a '\r" on it, again casting the BSTR to a char* is required. > for i = 1 to stringcount > strcat to BSTR, element[i] > strcat to BSTR, "\r" > return bstr; > On the VB end > declare function blabla lib "whatver.dll" () As String 'single string! > So in the calling function you would have something like this > dim sRet as Variant > sRet = Split(blabla(), chr$(10)) > That's about it. It's dirty, looks horrible, but it worked once. > I'll certainly be keeping my ear on this thread though for a better > way. :) > Come to think, i've never tried to create a BSTR array... hmmmm > If that's possible, it could be used directly with SysAllocString.. > Will try later maybe.. or even better, let us know if you do. :) > Regards, Frank
|
Wed, 12 Jan 2005 07:49:11 GMT |
|
 |
Max Bolingbrok #9 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
One way you could do this is to have VB pass the DLL a pointer to a callback, which you passed an ID to, and then the callback used another C function with the ID to retrieve that entry. Messy, but it should work. Max Bolingbroke
|
Wed, 12 Jan 2005 17:10:55 GMT |
|
 |
J Fren #10 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
On Sat, 27 Jul 2002 10:10:55 +0100, "Max Bolingbroke" Quote:
>One way you could do this is to have VB pass the DLL a pointer to a >callback, which you passed an ID to, and then the callback used another C >function with the ID to retrieve that entry. Messy, but it should work. >Max Bolingbroke
Hmm ... Max's suggestion reminds me of something I don't use C, but have done a fair bit of work on shunting data in and out of Delphi DLLs which is not too different. In general it is not hard to shove data down to DLLs - your array of Strings could be sent by Call MyDll( By Ref Ar$( 0 ) ) in which case you'll get a pointer on the stack that points to a 4 byte integer that points to the String Data - the 4 bytes before the String Data contains the string length. Unlike say arrays of Longs, where L(1) is 4 bytes after L(0), this is not too much use as VB helpfully makes an ANSII copy of the String - and passes that. However one can pass the VarPtr By Val which will give you a pointer to the pointer to the String Data - which will be in Unicode Modifying String Lengths is a pain - generally I have found that returning OleVariants is reliable - but that is not much use for your Array of Strings However this is where Max's suggestion comes in :- In pre-Windows BASIC I used to pass strings down to ASM, then to change the length of the String I would call a BASIC routine with the String and the new desired length as the parameters - by resizing the String within BASIC - but driven by ASM, the string would be correctly (re)allocated. One could easily send down the AddressOf a routine like :- StrSetLength( ByRef AString$, ByVal NewLength& ) and call that from within the DLL Obviously this is all a bit of a cludge - but it should work reliably
|
Wed, 12 Jan 2005 17:45:31 GMT |
|
 |
Julia #11 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
i manage to get an array returned to the VBside (and its not crashing !!!) but i seem to be going wrong somewhere: it looks like it is populated with "??" instead of the actual strings. can someone figure out whats wrong ?? SAFEARRAY* _stdcall ReturnStringArray(void) { int i; SAFEARRAY * psa; SAFEARRAYBOUND rgsabound[1]; rgsabound[0].lLbound = 0; rgsabound[0].cElements = 10; psa=SafeArrayCreate(VT_BSTR,1,rgsabound); BSTR* pArrayElements; // pointer to the elements of the array pArrayElements=(BSTR*) (psa)->pvData; //populating pvData for (i=0;i<10; i++){ pArrayElements[i]=SysAllocStringByteLen("test",4); Quote: }
return(psa); Quote: }
VB side : Private Declare Function ReturnStringArray Lib "DLLNAME" () As String() Dim strarray() As String strarray = ReturnStringArray() For i = 0 To UBound(strarray) MsgBox strarray(i) Next i thanks, Julian.
Quote:
> >hi, > > i have a VB application and a C DLL and i have been going crazy the past > >week trying to send string arrays back and forth !!! > >can someone pls help me out ? or atleast point me to some good website which > >explains clearly how to go abt this? > >i searched the web but cudn't get a clear idea of what they were trying to > >say. > >i need my DLL to return an array of strings which VB can read properly. is > >that possible?? > I've never got this to work too well either, or not to my liking > anyway. You do however have to return a BSTR allocated with > SysAllocString. Otherwise when your function exits, the pointer you've > returned is probably thrashed, by thetime VB gets to it.. > kinda like this pseudo.. > build the strings, whatever.. > add up the size of all strings on the way (+1 for each delimiter) > Use SysAlocStringLen to init the BSTR > the real crappy bit starts here... > sprintf the first element into the BSTR, cast as required. > strcat a '\r" on it, again casting the BSTR to a char* is required. > for i = 1 to stringcount > strcat to BSTR, element[i] > strcat to BSTR, "\r" > return bstr; > On the VB end > declare function blabla lib "whatver.dll" () As String 'single string! > So in the calling function you would have something like this > dim sRet as Variant > sRet = Split(blabla(), chr$(10)) > That's about it. It's dirty, looks horrible, but it worked once. > I'll certainly be keeping my ear on this thread though for a better > way. :) > Come to think, i've never tried to create a BSTR array... hmmmm > If that's possible, it could be used directly with SysAllocString.. > Will try later maybe.. or even better, let us know if you do. :) > Regards, Frank
|
Thu, 13 Jan 2005 11:12:45 GMT |
|
 |
J Fren #12 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
My bet is that VB is expecting Unicode Strings and your C side is creating ANSII strings. Try using StrConv on one of the strings in VB Quote:
>i manage to get an array returned to the VBside (and its not crashing !!!) >but i seem to be going wrong somewhere: >it looks like it is populated with "??" instead of the actual strings. >can someone figure out whats wrong ?? >SAFEARRAY* _stdcall ReturnStringArray(void) >{ >int i; >SAFEARRAY * psa; >SAFEARRAYBOUND rgsabound[1]; >rgsabound[0].lLbound = 0; >rgsabound[0].cElements = 10; >psa=SafeArrayCreate(VT_BSTR,1,rgsabound); >BSTR* pArrayElements; // pointer to the elements of the array >pArrayElements=(BSTR*) (psa)->pvData; >//populating pvData >for (i=0;i<10; i++){ >pArrayElements[i]=SysAllocStringByteLen("test",4); >} >return(psa); >} >VB side : >Private Declare Function ReturnStringArray Lib "DLLNAME" () As String() >Dim strarray() As String >strarray = ReturnStringArray() >For i = 0 To UBound(strarray) > MsgBox strarray(i) >Next i >thanks, >Julian.
>> >hi, >> > i have a VB application and a C DLL and i have been going crazy the >past >> >week trying to send string arrays back and forth !!! >> >can someone pls help me out ? or atleast point me to some good website >which >> >explains clearly how to go abt this? >> >i searched the web but cudn't get a clear idea of what they were trying >to >> >say. >> >i need my DLL to return an array of strings which VB can read properly. >is >> >that possible?? >> I've never got this to work too well either, or not to my liking >> anyway. You do however have to return a BSTR allocated with >> SysAllocString. Otherwise when your function exits, the pointer you've >> returned is probably thrashed, by thetime VB gets to it.. >> kinda like this pseudo.. >> build the strings, whatever.. >> add up the size of all strings on the way (+1 for each delimiter) >> Use SysAlocStringLen to init the BSTR >> the real crappy bit starts here... >> sprintf the first element into the BSTR, cast as required. >> strcat a '\r" on it, again casting the BSTR to a char* is required. >> for i = 1 to stringcount >> strcat to BSTR, element[i] >> strcat to BSTR, "\r" >> return bstr; >> On the VB end >> declare function blabla lib "whatver.dll" () As String 'single string! >> So in the calling function you would have something like this >> dim sRet as Variant >> sRet = Split(blabla(), chr$(10)) >> That's about it. It's dirty, looks horrible, but it worked once. >> I'll certainly be keeping my ear on this thread though for a better >> way. :) >> Come to think, i've never tried to create a BSTR array... hmmmm >> If that's possible, it could be used directly with SysAllocString.. >> Will try later maybe.. or even better, let us know if you do. :) >> Regards, Frank
|
Thu, 13 Jan 2005 13:47:04 GMT |
|
 |
Julia #13 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
one more thing: for the code below, do i have to worry abt memory leaks?? or does VB take care of freeing the memory allocated when its not using it anymore? thanks, Julian.
Quote: > My bet is that VB is expecting Unicode Strings and your C side is > creating ANSII strings. > Try using StrConv on one of the strings in VB
> >i manage to get an array returned to the VBside (and its not crashing !!!) > >but i seem to be going wrong somewhere: > >it looks like it is populated with "??" instead of the actual strings. > >can someone figure out whats wrong ?? > >SAFEARRAY* _stdcall ReturnStringArray(void) > >{ > >int i; > >SAFEARRAY * psa; > >SAFEARRAYBOUND rgsabound[1]; > >rgsabound[0].lLbound = 0; > >rgsabound[0].cElements = 10; > >psa=SafeArrayCreate(VT_BSTR,1,rgsabound); > >BSTR* pArrayElements; // pointer to the elements of the array > >pArrayElements=(BSTR*) (psa)->pvData; > >//populating pvData > >for (i=0;i<10; i++){ > >pArrayElements[i]=SysAllocStringByteLen("test",4); > >} > >return(psa); > >} > >VB side : > >Private Declare Function ReturnStringArray Lib "DLLNAME" () As String() > >Dim strarray() As String > >strarray = ReturnStringArray() > >For i = 0 To UBound(strarray) > > MsgBox strarray(i) > >Next i > >thanks, > >Julian.
> >> >hi, > >> > i have a VB application and a C DLL and i have been going crazy the > >past > >> >week trying to send string arrays back and forth !!! > >> >can someone pls help me out ? or atleast point me to some good website > >which > >> >explains clearly how to go abt this? > >> >i searched the web but cudn't get a clear idea of what they were trying > >to > >> >say. > >> >i need my DLL to return an array of strings which VB can read properly. > >is > >> >that possible?? > >> I've never got this to work too well either, or not to my liking > >> anyway. You do however have to return a BSTR allocated with > >> SysAllocString. Otherwise when your function exits, the pointer you've > >> returned is probably thrashed, by thetime VB gets to it.. > >> kinda like this pseudo.. > >> build the strings, whatever.. > >> add up the size of all strings on the way (+1 for each delimiter) > >> Use SysAlocStringLen to init the BSTR > >> the real crappy bit starts here... > >> sprintf the first element into the BSTR, cast as required. > >> strcat a '\r" on it, again casting the BSTR to a char* is required. > >> for i = 1 to stringcount > >> strcat to BSTR, element[i] > >> strcat to BSTR, "\r" > >> return bstr; > >> On the VB end > >> declare function blabla lib "whatver.dll" () As String 'single string! > >> So in the calling function you would have something like this > >> dim sRet as Variant > >> sRet = Split(blabla(), chr$(10)) > >> That's about it. It's dirty, looks horrible, but it worked once. > >> I'll certainly be keeping my ear on this thread though for a better > >> way. :) > >> Come to think, i've never tried to create a BSTR array... hmmmm > >> If that's possible, it could be used directly with SysAllocString.. > >> Will try later maybe.. or even better, let us know if you do. :) > >> Regards, Frank
|
Thu, 13 Jan 2005 14:14:03 GMT |
|
 |
Julia #14 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
that sure did the job !!!! thanks a bunch jsut one more thing : is there any way to do this conversion on the C side?? julian.
Quote: > My bet is that VB is expecting Unicode Strings and your C side is > creating ANSII strings. > Try using StrConv on one of the strings in VB
> >i manage to get an array returned to the VBside (and its not crashing !!!) > >but i seem to be going wrong somewhere: > >it looks like it is populated with "??" instead of the actual strings. > >can someone figure out whats wrong ?? > >SAFEARRAY* _stdcall ReturnStringArray(void) > >{ > >int i; > >SAFEARRAY * psa; > >SAFEARRAYBOUND rgsabound[1]; > >rgsabound[0].lLbound = 0; > >rgsabound[0].cElements = 10; > >psa=SafeArrayCreate(VT_BSTR,1,rgsabound); > >BSTR* pArrayElements; // pointer to the elements of the array > >pArrayElements=(BSTR*) (psa)->pvData; > >//populating pvData > >for (i=0;i<10; i++){ > >pArrayElements[i]=SysAllocStringByteLen("test",4); > >} > >return(psa); > >} > >VB side : > >Private Declare Function ReturnStringArray Lib "DLLNAME" () As String() > >Dim strarray() As String > >strarray = ReturnStringArray() > >For i = 0 To UBound(strarray) > > MsgBox strarray(i) > >Next i > >thanks, > >Julian.
> >> >hi, > >> > i have a VB application and a C DLL and i have been going crazy the > >past > >> >week trying to send string arrays back and forth !!! > >> >can someone pls help me out ? or atleast point me to some good website > >which > >> >explains clearly how to go abt this? > >> >i searched the web but cudn't get a clear idea of what they were trying > >to > >> >say. > >> >i need my DLL to return an array of strings which VB can read properly. > >is > >> >that possible?? > >> I've never got this to work too well either, or not to my liking > >> anyway. You do however have to return a BSTR allocated with > >> SysAllocString. Otherwise when your function exits, the pointer you've > >> returned is probably thrashed, by thetime VB gets to it.. > >> kinda like this pseudo.. > >> build the strings, whatever.. > >> add up the size of all strings on the way (+1 for each delimiter) > >> Use SysAlocStringLen to init the BSTR > >> the real crappy bit starts here... > >> sprintf the first element into the BSTR, cast as required. > >> strcat a '\r" on it, again casting the BSTR to a char* is required. > >> for i = 1 to stringcount > >> strcat to BSTR, element[i] > >> strcat to BSTR, "\r" > >> return bstr; > >> On the VB end > >> declare function blabla lib "whatver.dll" () As String 'single string! > >> So in the calling function you would have something like this > >> dim sRet as Variant > >> sRet = Split(blabla(), chr$(10)) > >> That's about it. It's dirty, looks horrible, but it worked once. > >> I'll certainly be keeping my ear on this thread though for a better > >> way. :) > >> Come to think, i've never tried to create a BSTR array... hmmmm > >> If that's possible, it could be used directly with SysAllocString.. > >> Will try later maybe.. or even better, let us know if you do. :) > >> Regards, Frank
|
Thu, 13 Jan 2005 14:11:29 GMT |
|
 |
J Fren #15 / 20
|
 passing (string) arrays from VB to C-DLL and vice versa
Hmm ... SysAllocStringByteLen Is there an equivalent for Unicode ... say SysAllocStringWordLen Don't know about the cleaning up, but I would figure that VB reckons that it 'owns' the Array descriptor that is returned, and would clean up - just as it does with OleVariants. Quote:
>one more thing: >for the code below, do i have to worry abt memory leaks?? >or does VB take care of freeing the memory allocated when its not using it >anymore? >thanks, >Julian.
|
Thu, 13 Jan 2005 15:33:23 GMT |
|
|
Page 1 of 2
|
[ 20 post ] |
|
Go to page:
[1]
[2] |
|