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!

Recommended Answers

All 5 Replies

Unicode?

Not sure, but it seems to me that Visual Basic passes strings in UTF-16 encoding and you are trying to convert from or to ASCII. What happens if non-ASCII characters (like accented or Chinese ones) are used?

I'm super proud

Woo!

w00t!

attaboy.

Unicode?

Not sure, but it seems to me that Visual Basic passes strings in UTF-16 encoding and you are trying to convert from or to ASCII. What happens if non-ASCII characters (like accented or Chinese ones) are used?

Well, back when I used VB a lot, I know if I tried to use anything but a basic character, it would show up as a question mark--also, the function I have written here is to change an ASCII string into a VB-readable format

>>unsigned short int

If you are compiling for UNICODE you should be using wchar_t datatype for portability. *nix computers define wchar_t as unsigned long int, which is obviously not the same as MS-Windows. And the last time I read the UNICODE standard was considering a 64-bit integer so that it could hold more Chinese graphic characters.

I was also under the impression that VB passed BSTR strings to C/C++.

commented: Since when are VB applications portable to Unix? :P +6

>> I was also under the impression that VB passed BSTR strings to C/C++.

You're right, but I just designed my function around the hex output that I got... I decided before I went to documentation I wanted to try and hack up a solution--more of an experience and problem solving exercise than a correct solution. Note that I'm not (obviously) working on any form of production code, just playing around in emacs.

However I did look up BSTR, and although it contains a length prefix which falls just before the first character, BSTR is a pointer to the first data character (which are double-byte), so it doesn't get in the way of my substandard solution.

>>*nix computers define wchar_t as unsigned long int

True, but VB doesn't run on *nix anyways ;)

commented: VB on *nix ... LOL :) +9
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.