So Maybe I shouldn't own a Copy Of Visual Studio 2008... (-;
I've programmed years and years ago, so I am a bit rusty.
So with help and tips from you I think I have what I need.
The main reason I wanted a defined Structure to overlap this Byte array is
that what I'm writing is a prototype and I'm not 100% sure what the end
result datastream might look like. Its going to have the main elements,
though we might want to add somethere here or there and move some things
around. I didn't want to have to do a bunch of while loops in my byte array
copying out chunks here and there.
With the Structure, I jsut change the Structure and all 'should' be pretty
good. I've re-written most of it as a standard class with managed objects,
Then that class deals with receiving the byte array, converting it to Public
objects, or definition of the values and then converts to Byte array.
I found 2 routines (RawSerialize, RawDeSerialize, they were in C#, so I had
to convert to VB.Net) that do the conversion from struct to byte array and
back, so those help, but I guess my understanding that the structs I was
defining were just pointers to 'nothing' that I needed to define the memory
space, and or objects of the 'right' length and assign to them before I
converted to the byte array.
I've included some of the code below.
<StructLayout(LayoutKind.Explicit, CharSet:=CharSet.Ansi)_
Structure SQL_PARMS
<FieldOffset(0)Dim Data_Type As Byte
<FieldOffset(4), MarshalAsAttribute(UnmanagedType.ByValArray,
SizeConst:=50)Dim Data_Value As Byte()
End Structure
<StructLayout(LayoutKind.Explicit, CharSet:=CharSet.Ansi)_
Structure SQL_COMMAND
<FieldOffset(0)Dim PLC_Type As Int16
<FieldOffset(4), MarshalAsAttribute(UnmanagedType.ByValArray,
SizeConst:=256)Dim SQLCmd As Byte()
<FieldOffset(260), MarshalAsAttribute(UnmanagedType.ByValArray,
SizeConst:=1080)Dim PARMS_BA As Byte()
<FieldOffset(1340), MarshalAsAttribute(UnmanagedType.ByValArray,
SizeConst:=708)Dim UNUSED As Byte()
End Structure
Public Function RawSerialize(ByVal anything As Object) As Byte()
Dim rawsize As Int16
Dim buffer As IntPtr
rawsize = Marshal.SizeOf(anything)
buffer = Marshal.AllocHGlobal(rawsize)
Marshal.StructureToPtr(anything, buffer, True)
Dim rawdatas(rawsize - 1) As Byte
Marshal.Copy(buffer, rawdatas, 0, rawsize)
Marshal.FreeHGlobal(buffer)
Return rawdatas
End Function
Public Function RawDeserialize(ByVal rawdatas As Byte(), ByVal anytype
As Type) As Object
Dim rawsize As Int16
Dim buffer As IntPtr
Dim retobj As Object
rawsize = Marshal.SizeOf(anytype)
If (rawsize rawdatas.Length) Then
Return Nothing
End If
buffer = Marshal.AllocHGlobal(rawsize)
Marshal.Copy(rawdatas, 0, buffer, rawsize)
retobj = Marshal.PtrToStructure(buffer, anytype)
Marshal.FreeHGlobal(buffer)
Return retobj
End Function
Public Sub GenStructureFromByte(ByVal Data As Byte())
Dim FixedSSQLCommand As New SQL_COMMAND
Dim FixedSQLParms As New SQL_PARMS
Dim i As Integer = 0
FixedSSQLCommand = RawDeserialize(Data,
FixedSSQLCommand.GetType)
PLC_Type = FixedSSQLCommand.PLC_Type
_RawSQLCmd = FixedSSQLCommand.SQLCmd
While (i < PARMS.Length)
PARMS(i) = New InternalSQL_PARMS
Dim ParmData As Byte() = New Byte(SIZE_OF_PARM_STRUCT) {}
System.Array.Copy(FixedSSQLCommand.PARMS_BA, (i *
SIZE_OF_PARM_STRUCT), ParmData, 0, SIZE_OF_PARM_STRUCT)
FixedSQLParms = RawDeserialize(ParmData,
FixedSQLParms.GetType)
PARMS(i).Data_Type = FixedSQLParms.Data_Type
PARMS(i).Data_Value = FixedSQLParms.Data_Value
i = i + 1
End While
End Sub
Public Function ReturnBytedata() As Byte()
Dim FixedSSQLCommand As New SQL_COMMAND
Dim FixedSQLParms As New SQL_PARMS
Dim SQLParmBytes As Byte()
Dim i As Integer = 0
FixedSSQLCommand.PLC_Type = PLC_Type
FixedSSQLCommand.SQLCmd = _RawSQLCmd
FixedSSQLCommand.PARMS_BA = New
Byte(SIZE_OF_PARM_ARRAY_ARRAY_BOUNDS) {}
FixedSSQLCommand.UNUSED = New
Byte(SIZE_OF_UNUSED_PARM_DATA_ARRAY_BOUNDS) {}
While (i < NumParms)
FixedSQLParms.Data_Type = PARMS(i).Data_Type
FixedSQLParms.Data_Value = PARMS(i).Data_Value
SQLParmBytes = RawSerialize(FixedSQLParms)
SQLParmBytes.CopyTo(FixedSSQLCommand.PARMS_BA, i *
SIZE_OF_PARM_STRUCT)
i = i + 1
End While
Return RawSerialize(FixedSSQLCommand)
End Function
"Göran Andersson" <gu***@guffa.comwrote in message
news:%2****************@TK2MSFTNGP06.phx.gbl...
Scott Townsend wrote:
>So I think I found the MarshalAsAttribute and reconfiguted my Structs.
THough now when I convert them to a pointer I'm getting an error.
So on this line of code below:
Marshal.StructureToPtr(DataToSend, ptrDataToSend, True)
It gives me the Following Error:
Type could not be marshaled because the length of an embedded array
instance does not match the declared length in the layout.
If I A dont have the Embedded Struct Array it seems to work out fine.
Here is all of the code:
<StructLayout(LayoutKind.Explicit, CharSet:=CharSet.Ansi)_
Structure SQL_PARMS
<FieldOffset(0)Dim Data_Type As Byte
<FieldOffset(1)Dim Unused As Byte
<FieldOffset(4), MarshalAsAttribute(UnmanagedType.ByValArray,
SizeConst:=50)Dim Data_Value As Byte()
End Structure
<StructLayout(LayoutKind.Explicit, CharSet:=CharSet.Ansi)_
Structure SQL_COMMAND
<FieldOffset(0)Dim PLC_Type As Int16
<FieldOffset(4), MarshalAsAttribute(UnmanagedType.ByValArray,
SizeConst:=256)Dim SQLCmd As Byte()
<FieldOffset(260), MarshalAsAttribute(UnmanagedType.ByValArray,
ArraySubType:=UnmanagedType.ByValArray, SizeConst:=20)Dim PARMS As
SQL_PARMS()
<FieldOffset(1340), MarshalAsAttribute(UnmanagedType.ByValArray,
SizeConst:=708)Dim UNUSED As Byte()
End Structure
Dim DataToSend As New SQL_COMMAND
Dim DataToReceieve As New SQL_COMMAND
Dim DataReceived As String
Dim iSizeOfStruct As Integer
Dim iSizeOfParms As Integer
Dim BytesToSend() As Byte
Dim mySQLParms(19) As SQL_PARMS
' initpacketData(DataToSend)
' initpacketData(DataToReceieve)
'Set up packet to send
DataToSend.PLC_Type = 100
DataToSend.SQLCmd = ConvertStringToByteArray(txtMessage.Text)
'Parm1
mySQLParms(0).Data_Type = PLCDataTypes.PLC_SINT16
mySQLParms(0).Data_Value = (New SQLParmData_FromValue(18)).Data
'Parm2
mySQLParms(1).Data_Type = PLCDataTypes.PLC_STRING
mySQLParms(1).Data_Value = (New SQLParmData_FromValue("Paul
Deas")).Data
DataToSend.PARMS = mySQLParms
iSizeOfStruct = Marshal.SizeOf(DataToSend)
'Set Up Our Pointer to Some Memory
Dim ptrDataToSend As IntPtr = Marshal.AllocHGlobal(2048)
'Copy the structure to our memory location @ pointer
Marshal.StructureToPtr(DataToSend, ptrDataToSend, True)
iSizeOfStruct = Marshal.SizeOf(DataToSend)
DataReceived = Marshal.PtrToStringUni(ptrDataToSend, 2048)
BytesToSend = ConvertStringToByteArray(DataReceived)
Dim ptrDataToReceieve As IntPtr = Marshal.AllocHGlobal(2048)
ptrDataToSend = Marshal.StringToHGlobalUni(DataReceived)
DataToReceieve = CType(Marshal.PtrToStructure(ptrDataToSend,
GetType(SQL_COMMAND)), SQL_COMMAND)
iSizeOfStruct = Marshal.SizeOf(DataToReceieve)
You don't assign anything to the UNUSED property, so that will be
undefined.
--
Göran Andersson
_____
http://www.guffa.com