943,725 Members | Top Members by Rank

Ad:
  • C Discussion Thread
  • Unsolved
  • Views: 512
  • C RSS
May 22nd, 2009
0

my first ever hack! (not a question)

Expand Post »
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:

vb Syntax (Toggle Plain Text)
  1. Public Declare Function return_string Lib "vbdll" _
  2. (ByVal somestring As String) As String
  3.  
  4. 'snip
  5.  
  6. 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:

  1. __declspec(dllexport) void __stdcall sendstringinfo(unsigned short int *string){
  2. unsigned short int *lit = L"O, Y HALLO THAR!!";
  3.  
  4. while(send_output(*string),*string++);
  5. nl();
  6. while(send_output(*lit),*lit++);
  7. }

and produced output like this:

  1. 2C4F 5920 4820 4C41 4F4C 5420 4148 2152 0021 0000
  2.  
  3. 004F 002C 0020 0059 0020 0048 0041 004C 004C 004F 0020 0054 0048 0041 0052 0021 0021 0000
  4.  
  5. [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.

  1. unsigned short int* vbify(unsigned short int *failstring){
  2.  
  3. int length=0;
  4. int i=0;
  5. int pos=0;
  6. int step=0;
  7. unsigned short int *newstr;
  8.  
  9. while(length++,*failstring++);
  10. failstring -= length;
  11. newstr = malloc(length * sizeof(short));
  12.  
  13. for(; i<length; ++i){
  14. switch(step){
  15. case 0:
  16. newstr[pos] = failstring[i];
  17. step = 1;
  18. break;
  19. case 1:
  20. if(failstring[i]!=0){
  21. newstr[pos] |= failstring[i] << 8;
  22. ++pos;
  23. step = 0;
  24. } else {
  25. newstr[pos + 1] = 0;
  26. }
  27. break;
  28. }
  29. }
  30.  
  31. return newstr;
  32.  
  33. }

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)

  1. __declspec(dllexport) unsigned short int* __stdcall get_some_string(){
  2. unsigned short int *temp_str;
  3. temp_str = L"Hi, I'm your C DLL, just handing you some dataz.";
  4. temp_str = vbify(temp_str);
  5. strcpy(vb_buffer,temp_str);
  6.  
  7. return vb_buffer;
  8. }

and it would produce a message box saying "Hi, I'm your C DLL, just handing you some dataz."

Woo!
Similar Threads
Reputation Points: 19
Solved Threads: 1
Junior Poster
winrawr is offline Offline
110 posts
since Dec 2008
May 22nd, 2009
0

Re: my first ever hack! (not a question)

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?
Last edited by nalply; May 22nd, 2009 at 10:05 am.
Reputation Points: 10
Solved Threads: 1
Newbie Poster
nalply is offline Offline
8 posts
since May 2009
May 22nd, 2009
0

Re: my first ever hack! (not a question)

Click to Expand / Collapse  Quote originally posted by winrawr ...
I'm super proud

Woo!
w00t!

attaboy.
Reputation Points: 2143
Solved Threads: 178
Posting Maven
jephthah is offline Offline
2,567 posts
since Feb 2008
May 22nd, 2009
0

Re: my first ever hack! (not a question)

Click to Expand / Collapse  Quote originally posted by nalply ...
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
Reputation Points: 19
Solved Threads: 1
Junior Poster
winrawr is offline Offline
110 posts
since Dec 2008
May 23rd, 2009
0

Re: my first ever hack! (not a question)

>>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++.
Last edited by Ancient Dragon; May 23rd, 2009 at 8:42 pm.
Sponsor
Team Colleague
Featured Poster
Reputation Points: 5608
Solved Threads: 2282
Retired and Enjoying Life
Ancient Dragon is online now Online
21,950 posts
since Aug 2005
May 23rd, 2009
1

Re: my first ever hack! (not a question)

>> 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
Reputation Points: 19
Solved Threads: 1
Junior Poster
winrawr is offline Offline
110 posts
since Dec 2008

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C Forum Timeline: in range strcpy
Next Thread in C Forum Timeline: Call for Help





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC