944,038 Members | Top Members by Rank

Ad:
Apr 23rd, 2005
0

Coverting a string to a byte array

Expand Post »
I have been given the following code to convert a string to a "byte array" (which is then passed to other software) but it does not appear to work. I have practically never needed to use a function and am even less familiar with the data type byte and Hex numbers. I think the Val("&H") + Mid$(QueryStr, ByteIndex * 2 + 1, 2) part is wrong (Very!). Any clues?

Type DATAQUERY
Data(SP_MAX_QUERY_SIZE - 1) As Byte
End Type

Global Const SP_MAX_QUERY_SIZE = 56

************************
The first QueryStr is "0C65450C"
I think QueryLength is 8.

************************

Public Function StringToDataQuery(QueryStr As String, QueryLength As Integer) As DATAQUERY

'This converts the query string to a query byte array
Dim ByteIndex As Integer
ByteIndex = 0
For ByteIndex = 0 To QueryLength - 1
StringToDataQuery.Data(ByteIndex) = _
Val("&H") + Mid$(QueryStr, ByteIndex * 2 + 1, 2)
Next ByteIndex

End Function
Similar Threads
Reputation Points: 10
Solved Threads: 0
Light Poster
MrConfused is offline Offline
32 posts
since Mar 2005
Apr 24th, 2005
0

Re: Coverting a string to a byte array

I have figured out the syntax was wrong. The following seems o.k.

Public Function StringToDataQuery(QueryStr As String, QueryLength As Integer) As DATAQUERY
'This converts the query string to a query byte array
Dim ByteIndex As Integer

For ByteIndex = 0 To QueryLength - 1
StringToDataQuery.Data(ByteIndex) = Val("&H" + Mid$(QueryStr, ByteIndex * 2 + 1, 2))
Next ByteIndex
End Function

I will be talking to the Co. that gave me the code tomorrow. The .data part I presume communicates with their program (which is linked to my code, but I have no clue exactly what their program does!). It's a shame the documentation provided by the Company is so vague. 218 pages of "developer instructions", yet you read the lot and about 200 pages tell you what the "dongle" can do, and about the other 18 vaguely hint at what the programmer has to do. Not even any examples. Rubbish. By the way the reason I am having to sort this mess out is they claim their product is VB compatible, yet their technical person says "oh, the key expects the argument to be in "c" format, so a VB string (which their own documentation says will work!) will NOT work! The VB string has to be converted to the VB "BYTE" format, then sent to the key for a response, then the response has to be converted back to a string for comparison. "Have you any programs you can email me that show how to do this?". "No". Just great isn't it! If I have no luck tomorrow maybe I'll post the product here so people can avoid it.
Reputation Points: 10
Solved Threads: 0
Light Poster
MrConfused is offline Offline
32 posts
since Mar 2005
Apr 25th, 2005
0

Re: Coverting a string to a byte array

There are only a few words that come to mind, but "wow" says it all.
Team Colleague
Reputation Points: 361
Solved Threads: 214
Taboo Programmer
Comatose is offline Offline
2,413 posts
since Dec 2004
Jan 7th, 2007
0

Re: Coverting a string to a byte array

theres a big problem when trying to talk to api or c applications/libraries using VisualBasic and that's the String, actually I've been doing a fair bit of research and there is a brilliant piece on it in the MSDN library that ships with VisualBasic 6.0 Professinal edition in the Books section under Hardcore Visualbasic.

VB nativley uses unicode where it can, Windows95 through NT accepts LPSTR type strings, NT prefers LPWSTR type strings (W for Widechar otherwise known as unicode).

VB3 used HLSTR which is a pointer, to a pointer with a length attribute then to the character stream which is your regular 8-bit byte-per-char string.

VB6 uses BSTR which is a null-terminated widechar string, inside the vb programming environment "this" has a length of 4 characters, in memory it's 10 characters (counting the wNull at the tail and not including it's length record).

The Byte datatype serves two purposes, one is a single unsigned byte for use as flags or values, can be used as a 'typeless' variable to store unformatted datablobs, the other purpose is to behave just like a C/C++/Java char datatype.

The dynamic byte array is compatible with the String datatype, i.e.
Dim bText() as byte
Dim MyString as String: MyString = "COWS!"
bText = MyString

bText will contain the word "COWS!"

debug.print bText
will reveal that fact, and even MsgBox although sometimes you need to convince it to let you do it, it's not a huge drama.

bText will also contain the UNICODE version of the string unlike various routines in VB that automatically convert to ASCII/ANSI strings which for some things are absolutley useless.

A fixed sized array (even one that can be redimmed) generally and 99.9% of the time will not allow you to directly assign the VB string to it.

This is my working solution to your code, if you test it with an 8 byte entry the first 8 bytes in the data array become occupied right up to the very top. PLEASE SAVE ANY CHANGES YOU MAKE BEFORE RUNNING THIS CODE, and feel free to try it in a secondary copy just in case it's not compatible at all, because if for any reason CpyMem violates memory space the VBIDE will exit with no warning!

vb Syntax (Toggle Plain Text)
  1.  
  2. Declare Sub CpyMem Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cLength As Long)
  3.  
  4. Type DATAQUERY
  5. Data(0 To 55) As Byte 'feel free to replace my array notation with your constant
  6. End Type
  7.  
  8. Function StringToDataQuery(QueryStr As String, QueryLength As Long) As DATAQUERY
  9. Dim DQTemp As DATAQUERY 'because I'm bending the rules a little I do it this way
  10. Dim bStrTemp() As Byte
  11. bStrTemp = StrConv(QueryStr, vbFromUnicode) 'if you wish to preserve the unicode encoding
  12. 'this will causee the code to change a bit, but my understandign is that you want to trim
  13. 'the unicode encoding completley, there are two ways to go from here, one is a loop which
  14. 'assigns each byte value to the dataquery byte array, or there'st the more direct method
  15.  
  16. CpyMem DQTemp.Data(0), bStrTemp(0), QueryLength
  17.  
  18. '----Disregard if you already have experience with CopyMemory----
  19. 'I will now explain something very important, CpyMem or CopyMemory has no type checking
  20. 'it hammers memory from one source to another to whatever size you specify
  21. 'it is up to you to do bounds checking, i.e. that QueryLength MUST NOT be greater than
  22. 'the .Data field, because if it is you overwrite someone elses memory and it can either
  23. 'result in your program exiting with no warning, or crashing several programs even causing
  24. 'a system crash. CpyMem uses the datatype ANY which is a special case for API calls
  25. 'ANY passes a pointer to respective library, it works fine for everything EXCEPT
  26. 'visualbasic strings so don't even bother trying it, there is a work around if you do need to
  27. 'but it's too early in the morning for me to write it up.
  28. StringToDataQuery = DQTemp
  29.  
  30. End Function

CpyMem or CopyMemory plays with pointers in vb, what I've given you is pretty straight forward and can be used with everything short of the actual VB string itself (which I won't explain why at this moment)

Yes VisualBasic has pointers, No it's not very popular, Purists would have my head for even mentioning them as they can be VERY DANGEROUS if you haven't throught out carefully about how it's going to interact with something especially when there are no bounds checking or anything else.

What you do with pointers and CpyMem is entirley up to you but be aware VB will not protect you, will not enforce Type checks AT ALL when using this arrangement.

It should be noted that RtlMoveMemory is an elegant fast solution to a loop with many iterations something that at this stage VB doesn't have a real match for. AND please be aware that "RtlMoveMemory" in the Decleration at the top of the code is CaSe-SeNsITiVe!

Another point to note is that you cannot just:

CopyMemory DQtemp.Data, bStrTemp, QueryLength

why? because you're passing the API a pointer to a pointer, not a Pointer to useable memory. (don't ask, just trust me on this one), if you want to hammer data using CopyMemory/CpyMem ALWAYS make sure that the first item in the array you want to manipulate is passed.

You can even CpyMemory DQTemp.Data(4), bStrTemp(4), 4

If this has been helpful let me know, if not, disregard. But I've had some suprising success working in VB using the api.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
philaus76 is offline Offline
1 posts
since Jan 2007
May 22nd, 2010
0
Re: Coverting a string to a byte array
Skip the part CByte() for type casting unless you do recalculation of the values in the string as ASC returns an Integer and at times could cause an overflow in the byte array.

Visual Basic 4 / 5 / 6 Syntax (Toggle Plain Text)
  1. Public MyByteArr() As Byte
  2. Public Sub StringToByteArray(ByVal s As String)
  3. Dim i As Long
  4. ReDim MyByteArr(Len(s) - 1) As Byte
  5. For i = 0 To Len(s) - 1
  6. MyByteArr(i) = CByte(Asc(Mid(s, i + 1, 1)))
  7. Next i
  8. End Sub

Of course it's slower than copy men and stuff but it solves the problem without third party API's.

On the side of Unicode vs. ANSII code... in this case you can discard such discussions if you only use a straight forward string read into VB.

Why VB even started casting everything to Unicode is beyond me, except for one reason and that would be sales based for M$ so they force you to move over to C/C++ and cannot use simple VB to display said unicode in the legacy applications.

To bad that they dropped it, when the only thing VB needed to continue its life was unicode output support practically.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
10e12 is offline Offline
2 posts
since May 2010
May 22nd, 2010
0
Re: Coverting a string to a byte array
10e12,

Welcome to the forums. Hope you can become a valued member but I must inform you that you are GUILTY OF NECROPOSTING!!! Not a nice thing to do in any formum as most people who have replied to the thread recieve an email...

Also: a much faster version would be...
Visual Basic 4 / 5 / 6 Syntax (Toggle Plain Text)
  1. MyByteArr = StrConv(s, vbFromUnicode)
Reputation Points: 156
Solved Threads: 296
Posting Virtuoso
vb5prgrmr is offline Offline
1,670 posts
since Mar 2009
May 23rd, 2010
0
Re: Coverting a string to a byte array
thanks for the Much faster suggestion.
I was just copying in my code I just wrote for changing 32 bytes at a time.
Not much speed required for that junk snippet.

As far as Necroposting goes...
I have no clue what you're referring to as I stick to Plain English, Swedish, German and occasionally Japanese but in neither one of those do I find a dictionary explaining the term necroposting.

As far as receiving replies to threads through e-mail so do I, and most of us who have been on forums for about 15 years now, we do weed a lot of our stuff already in the inbox or simply select to not receive replies for certain threads.

If that was unpleasant for you, then I apologize.
Last edited by 10e12; May 23rd, 2010 at 3:04 pm.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
10e12 is offline Offline
2 posts
since May 2010
May 24th, 2010
0
Re: Coverting a string to a byte array
Necro from the latin-dead, posting... got it? Well here it is again.... dead thread posting...
Reputation Points: 156
Solved Threads: 296
Posting Virtuoso
vb5prgrmr is offline Offline
1,670 posts
since Mar 2009
May 24th, 2010
0
Re: Coverting a string to a byte array
your function is ok but u have a problem use this
Val("&H" + Mid$(QueryStr, ByteIndex * 2 + 1, 2))
not
Val("&H") + Mid$(QueryStr, ByteIndex * 2 + 1, 2)
Reputation Points: 10
Solved Threads: 10
Junior Poster in Training
omoridi is offline Offline
72 posts
since Sep 2009
Nov 8th, 2010
0
Re: Coverting a string to a byte array
Stop griping! I just read this entry and it is already 2010!
Reputation Points: 10
Solved Threads: 0
Newbie Poster
FSandlewould is offline Offline
7 posts
since Jun 2010

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.
This thread is currently closed and is not accepting any new replies.
Previous Thread in Visual Basic 4 / 5 / 6 Forum Timeline: Record Already Exists
Next Thread in Visual Basic 4 / 5 / 6 Forum Timeline: Runtime Error, pls help





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


Follow us on Twitter


© 2011 DaniWeb® LLC