passing (string) arrays from VB to C-DLL and vice versa 
Author Message
 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  
 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  
 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  
 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  
 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  
 passing (string) arrays from VB to C-DLL and vice versa
Oh, and don't multipost.


Wed, 12 Jan 2005 00:32:31 GMT  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 
 [ 20 post ]  Go to page: [1] [2]

 Relevant Pages 

1. passing (string) arrays from VB to C-DLL and vice versa

2. passing (string) arrays from VB to C-DLL and vice versa

3. Byte Array to String and Vice Versa?

4. HELP: How to convert a byte array into a string, and vice versa

5. ListBox.Items to String and vice versa

6. Using DLL, passing an array of integers to Vb from C and vice versa.

7. Anybody ever pass an array from a C++ DLL to a VB app or vice versa?

8. Newbi to VB Pro 3.0 - How to link in c++ (or vice versa)

9. Transferring files from VB to MVS and vice versa

10. VB to ASP and vice versa

11. Converting RTF files to HTML in VB and vice versa

12. VB to ASP and vice versa

 

 
Powered by phpBB® Forum Software