rtlmovememory

  • Thread starter Thread starter John Koisch
  • Start date Start date
J

John Koisch

All,

In vb6.0, some of our co-developers used the following ...

Private Declare Sub MoveMemory Lib "kernel32.dll"
Alias "RtlMoveMemory" (ByVal dst As Any, ByVal src As
Any, ByVal cb As Long)

This gave us some errors when we tried to use in VS.Net.
We did change it to typed:

Private Declare Sub MoveMemory Lib "kernel32.dll"
Alias "RtlMoveMemory" (ByVal dst As Byte, ByVal src As
String, ByVal cb As Long)

However, now we're getting

An unhandled exception of
type 'System.NullReferenceException' occurred in
ConsoleApplication2.exe

Additional information: Object reference not set to an
instance of an object.

Pardon the length, but code follows. Any help - this is
urgent ...

Thx
John

Module Module1Attribute


Private Declare Sub MoveMemory Lib "kernel32.dll"
Alias "RtlMoveMemory" (ByVal dst As Byte, ByVal src As
String, ByVal cb As Long)

Private Declare Sub ReMoveMemory Lib "kernel32.dll"
Alias "RtlMoveMemory" (ByVal src As String, ByVal dst As
Byte, ByVal cb As Long)

Sub Main()
Dim message As String

message = "Junk Junk Junk Junk"

Console.WriteLine(EncodeString(message))
End Sub

Public Function EncodeString(ByVal InString As
String, Optional ByVal StringToBinaryConv As Boolean =
False) As String
Dim OutString As String
Dim I As Long
Dim UnCodedArray() As Byte
Dim CodedArray() As Byte

' Begin:SCR #35900; Developer: Mag 05/08/2003
12:32 PM
If Trim$(InString) = "" Then
EncodeString = ""
Exit Function
End If
' End: SCR #35900;

'To handle compressed encounter data
'If StringToBinaryConv Then
'InString = StrConv(InString, vbUnicode)
'End If

'Pad will null characters if necessary
If Len(InString) Mod 3 <> 0 Then
Dim x As Int32
For x = 1 To (3 - Len(InString) Mod 3)
InString = InString & vbNullChar
Next
'nString = InString & String(3 - Len
(InString) Mod 3, Chr(0))
End If

'Convert string to a byte array. This is MUCH
faster than the Asc/Chr combo.
StringToByteArray(InString, UnCodedArray)

'Make sure our output array is the correct size
ReDim CodedArray(((Len(InString) / 3) * 4) - 1)

For I = 0 To (Len(InString) / 3) - 1
'Encode 4 bytes at a time
CodedArray(I * 4 + 0) = UnCodedArray(I * 3 +
0) \ 4 + 32
CodedArray(I * 4 + 1) = ((UnCodedArray(I * 3
+ 0) Mod 4) * 16) + (UnCodedArray(I * 3 + 1) \ 16 + 32)
CodedArray(I * 4 + 2) = ((UnCodedArray(I * 3
+ 1) Mod 16) * 4) + (UnCodedArray(I * 3 + 2) \ 64 + 32)
CodedArray(I * 4 + 3) = (UnCodedArray(I * 3 +
2) Mod 64) + 32

'Check for spaces and eliminate them
If CodedArray(I * 4 + 0) = 32 Then CodedArray
(I * 4 + 0) = 96
If CodedArray(I * 4 + 1) = 32 Then CodedArray
(I * 4 + 1) = 96
If CodedArray(I * 4 + 2) = 32 Then CodedArray
(I * 4 + 2) = 96
If CodedArray(I * 4 + 3) = 32 Then CodedArray
(I * 4 + 3) = 96
Next I
ByteArrayToString(CodedArray, OutString)

'Replace characters that cannot be sent in XML
'OutString = FilterRtfToXml(OutString)

EncodeString = OutString
End Function

Private Sub StringToByteArray(ByVal StringIn As
String, ByVal ByteArray() As Byte)
Dim lBytes As Long

If Len(StringIn) = 0 Then Exit Sub

lBytes = Len(StringIn)
ReDim ByteArray(lBytes - 1)

MoveMemory(ByteArray(0), StringIn, lBytes)



End Sub
Private Sub ByteArrayToString(ByVal ByteArray() As
Byte, ByVal StringOut As String)
Dim lBytes As Long

If LBound(ByteArray) > 0 Then Exit Sub 'lBound
MUST be 0
lBytes = UBound(ByteArray) + 1
StringOut = Convert.ToString(lBytes, 0)
ReMoveMemory(StringOut, ByteArray(0), lBytes * 2)
End Sub

End Module
 
John,

I suggest you use one of the System.Text.Encoding subclasses for
converting String <-> Byte() instead.



Mattias
 
John,
In addition to what Mattias stated about using System.Text.Encoding to
convert Strings to Byte.

If you want to move elements of one array to another array, use
System.Buffer.BlockCopy. You can use System.Buffer.ByteLength to find out
how many bytes there are. String has a ToCharArray to convert the String to
an array of Char.

Note BlockCopy will move 2 bytes for each Char, while Encoding may convert 1
Char to 1 Byte.

Buffer.BlockCopy is the .NET equivalent of RtlMoveMemory!

Hope this helps
Jay
 
Thanks for your comments. We are, however, in the not
unheard of situation of having to deal with OPC (other
people's code). This actually comes to us from a
different shop in the enterprise, and they are offering
no support, etc. SO, to make this process work, we are 1)
stuck with a bad process, and 2) stuck with their code.

Otherwise, I would be happy to use other, better, faster
solutions.

So, any more thoughts on the nature of our error?

John
-----Original Message-----
John,
In addition to what Mattias stated about using System.Text.Encoding to
convert Strings to Byte.

If you want to move elements of one array to another array, use
System.Buffer.BlockCopy. You can use
System.Buffer.ByteLength to find out
 
John,
no support, etc. SO, to make this process work, we are 1)
stuck with a bad process, and 2) stuck with their code.
Huh???

As far as I can tell: To make this process work you need do one of the
following instead of calling RtlMoveMemory:
1. use the Buffer class
http://msdn.microsoft.com/library/d...us/cpref/html/frlrfSystemBufferClassTopic.asp

2. use the Encoding class
http://msdn.microsoft.com/library/d...us/cpref/html/frlrfSystemBufferClassTopic.asp

Luckily your code encapsulates the call to RtlMoveMemory into to sub
routines.

Both are very easy to use.

The problem as I see it is that the 'faster than Asc/Chr combo' suggests you
want to use the Encoding class, while RtlMoveMemory suggests you want to use
Buffer.BlockCopy.

Buffer.BlockCopy will more closely match how you are currently using
RtlMoveMemory. Whether that is correct or not I'm not sure.

Oh! and by the way, String objects are immutable in .NET, your
ByteArrayToString routine should use a System.Text.StringBuilder instead.

Hope this helps
Jay
 
John,
I should add to my other post that the Encoding class has shared properties
for different encodings, for example there is Encoding.Unicode which will
convert strings into an array of bytes of Unicode characters (remember each
Unicode character will take up two bytes). There is a Encoding.Default which
will convert strings into the char set currently set for Windows.

Also the Encoding class has a GetBytes method that will convert a string
into an array of bytes. Plus an GetString that will convert an array of
bytes to a string.

Hope this helps
Jay
 
Back
Top