CopyMemory doesn't work with destination as Array of Fixed Length Strings?
I have a byte array called mybytearray with the ascii (1 byte per character) characters "ABCD1234" and would like to split it into 2 equal parts of 4 characters each so I have an array of fixed length strings like this
Code:
dim mystrarray() as string*4
redim mystrarray(1)
I then need to copy this so I have declared CopyMemory using "as any" for the source and destination. The following code should make the bytes of the byte array copy into the array of fixed length strings
Code:
copymemory mystrarray(0),mybytearray(0),8
This CRASHES THE PROGRAM THOUGH!!!!
So then I tried
Code:
copymemory byval strptr(mystrarray(0)),mybytearray(0),8
This didn't crash the program, but the destination array is not containing the input data!
So then I tried
Code:
copymemory byval strptr(mystrarray(0)),byval strptr(strconv(mybytearray(),vbunicode)),8
Again THE DESTINATION ARRAY IS NOT RECEIVING THE DATA FROM THE SOURCE!!!!!!!!!
Someone please help me. Thanks, in advance.
Re: CopyMemory doesn't work with destination as Array of Fixed Length Strings?
You do realize, that you're trying to copy 8 bytes to the destination-string? And that your destination-string is declared to take 4 characters, 2 bytes each character (unicode).
And i would try varptr on the source-array
Re: CopyMemory doesn't work with destination as Array of Fixed Length Strings?
This way works:
Code:
Private Type FixedStrType 'This ensures the fixed-length
String_0 As String * 4 'strings are contiguous in memory
String_1 As String * 4 'Fixed-length strings are Unicode too
End Type 'Verify that by assigning any Unicode char
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Sub Main()
Dim MyByteArray() As Byte, MyFixedStr As FixedStrType
MyByteArray = "ABCD1234" 'UBound(MyByteArray) = 15
'Avoid Unicode-ANSI conversion by passing a pointer to MyFixedStr
'Prevent CopyMemory from copying more than MyFixedStr can receive
'by limiting the number of bytes copied to the size of FixedStrType
CopyMemory ByVal VarPtr(MyFixedStr), MyByteArray(0), LenB(MyFixedStr)
MsgBox MyFixedStr.String_0 & vbCrLf & MyFixedStr.String_1, vbInformation
End Sub
Re: CopyMemory doesn't work with destination as Array of Fixed Length Strings?
Well, at least i was close :lol:
Re: CopyMemory doesn't work with destination as Array of Fixed Length Strings?
A userdefined type won't work for me. My input is a variable number of fixed length strings based on what file I'm loading. The number of fixed length strings will vary but the length of each string will NOT vary. So I must have something that can load a block of memory into an array of fixed length strings. So the formula should be
Total Bytes = Number of Array elements * Number of Fixed Length Characters * 2
(last "*2" is because of the fact that Unicode is 2 bytes per character)
This should let me copy from a byte array directly into the array of fixed length strings, without any extra stupid hocus pocus to make VB "like" what I'm telling it to do.
But it doesn't work. Why not?
Re: CopyMemory doesn't work with destination as Array of Fixed Length Strings?
The Total Bytes will depend on how you've populated the Byte Array in the first place (i.e. have you discarded the vbNewLines)
If you have, then the Total Bytes will be UBound(ByteArray) + 1
This appears to work:
Code:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)
Private Const STRING_LENGTH As Integer = 8 ' Number of characters in a line of data
Private Const HALF_LENGTH As Integer = STRING_LENGTH / 2
Private Sub Command_Click()
Dim intFile As Integer
Dim intI As Integer
Dim intJ As Integer
Dim lngRecords As Long
Dim bytData() As Byte
Dim strLines() As String
Dim strResults() As String * HALF_LENGTH
Dim strTemp(1) As String * STRING_LENGTH
intFile = FreeFile()
'
' Read the entire file into a Byte Array
' Note that you can only use this method if there
' are no blank lines in the file
'
Open "C:\MyDir\MyData.txt" For Input As intFile
bytData = Input(LOF(intFile), intFile)
Close intFile
'
' Calculate the Number of Records
' and establish the Results Array size
'
lngRecords = (UBound(bytData) + 1) / (2 * (STRING_LENGTH + 2))
ReDim strResults((lngRecords * 2) - 1)
Do
'
' Copy the data to a temporary string
' and put the converted from Unicode data into the Results Array
'
CopyMemory ByVal strTemp(0), bytData(intJ), STRING_LENGTH
strResults(intI) = StrConv(strTemp(0) & strTemp(1), vbFromUnicode)
intJ = intJ + STRING_LENGTH
'
' Check for end of line and skip over
' the vbNewLine
'
If (intJ - ((intI \ 2) * 4)) Mod (STRING_LENGTH * 2) = 0 Then
intJ = intJ + 4
End If
intI = intI + 1
Loop Until intI > UBound(strResults)
For intI = 0 To UBound(strResults)
Debug.Print strResults(intI)
Next intI
End Sub