alright, I did this without the help of documentation or help forums, I just sorta, figured it out on my own--and hacked together some code to make it work, and I'm super proud, so bare with me:
I compiled a C DLL, which was loaded into a VB6 app. The C DLL had a function which took an unsigned short* as an argument, and then just returned that argument. I did this in VB:
Public Declare Function return_string Lib "vbdll" _
(ByVal somestring As String) As String
'snip
MsgBox return_string("Y HALLO THAR!")
This (obviously) produced a message box containing the text "Y HALLO THAR!" So I figured that it was easy to pass strings back and forth from VB to C and back to VB. Sooooo wrong. So I wrote a function, which returned an unsigned short* which pointed to a literal: L"Oh, Hello there, sir!"
. Well it didn't work as I had expected--in fact, the program crashed. I decided that since I could pass a VB string right through a C function without any problems, but not write my own, I figured that VB was formatting the strings weird.
So I create a form, with a textbox, with system font (just so it's nice and easy to see). And create a VB function which takes an Integer, and then writes that integer in hex format to the textbox, followed by a space. Then a similar function which writes a newline. I passed those functions to function pointers in the DLL via the AddressOf operator in VB. and, wrote a function which took an unsigned short*. The function called VB to write out each integer in the string to the textbox, then I pointed to a literal of the same string, and did the same. The function was like so:
__declspec(dllexport) void __stdcall sendstringinfo(unsigned short int *string){
unsigned short int *lit = L"O, Y HALLO THAR!!";
while(send_output(*string),*string++);
nl();
while(send_output(*lit),*lit++);
}
and produced output like this:
2C4F 5920 4820 4C41 4F4C 5420 4148 2152 0021 0000
004F 002C 0020 0059 0020 0048 0041 004C 004C 004F 0020 0054 0048 0041 0052 0021 0021 0000
[added zeros for clarity]
ha! So it's in little-endian encoding--sort of. I have to iterate through each value of the C-ish string, and for every other value, shift it in to the high end of the previous value. If there's an odd number of characters, skip the shifting and append 0 to the end (otherwise the 0000 wouldn't get at the end, the least significant 00 would get shifted into 0021, just resulting in the same 0021--I guess there has to be a whole 0 value at the end). So I wrote a vbify function--probably not the most efficient way to do it, I haven't tried to optimize it yet, I just started writing this excitedly when I got it to work.
unsigned short int* vbify(unsigned short int *failstring){
int length=0;
int i=0;
int pos=0;
int step=0;
unsigned short int *newstr;
while(length++,*failstring++);
failstring -= length;
newstr = malloc(length * sizeof(short));
for(; i<length; ++i){
switch(step){
case 0:
newstr[pos] = failstring[i];
step = 1;
break;
case 1:
if(failstring[i]!=0){
newstr[pos] |= failstring[i] << 8;
++pos;
step = 0;
} else {
newstr[pos + 1] = 0;
}
break;
}
}
return newstr;
}
so, if I wanted VB to go say, MsgBox get_some_string
, I could write get_some_string in C like this:
(note, I would have defined a VB string buffer, and given it by pointer to C, so this data could be in the VB app rather than in the DLL)
__declspec(dllexport) unsigned short int* __stdcall get_some_string(){
unsigned short int *temp_str;
temp_str = L"Hi, I'm your C DLL, just handing you some dataz.";
temp_str = vbify(temp_str);
strcpy(vb_buffer,temp_str);
return vb_buffer;
}
and it would produce a message box saying "Hi, I'm your C DLL, just handing you some dataz."
Woo!