K
kelli
i am new to c# so if this is a trivial problem, forgive me! i've
searched the web and after 2 days still cannot solve it. i am
converting a c++ application to c# - the problem code is listed below.
the c++ code uses a byte array (msg[256]) to hold a serial message.
since the message can be of different layouts, the array is cast to the
appropriate layout "type" (struct SERIAL_CAN_MSG_TYPE, in this
example). to complicate things, there is an array at the end of the
SERIAL_CAN_MSG_TYPE struct, data[], which can hold variable data types
(byte, ushort, and uint) -AND- can be of variable length (more than 2
elements). with that said, here's the c++ code:
---------- start c++ code -------------
typedef unsigned char INT_8U;
typedef unsigned short int INT_16U;
typedef short int INT_16;
....
typedef struct
{
INT_8U priority;
INT_16 dlc;
INT_8U messageType;
INT_8U channel;
INT_8U data[2];
}SERIAL_CAN_MSG_TYPE;
....
INT_8U msg[256];
SERIAL_CAN_MSG_TYPE* msgPtr;
msgPtr = (SERIAL_CAN_MSG_TYPE*)&(msg[0]);
....
// uses casting to assign a ushort to the byte array (data)
for(i = 0; i < 64; i++)
{
*((INT_16U *)&msgPtr->data[i*4]) = spoolChannel.address;
}
------- end c++ code --------
..... and here's my attempt at converting to c#:
----------- start c# code ------------
[StructLayout(LayoutKind.Explicit)]
unsafe public struct SERIAL_CAN_MSG_TYPE
{
[FieldOffset(0)]public byte priority;
[FieldOffset(1)]public short dlc;
[FieldOffset(3)]public byte messageType;
[FieldOffset(4)]public byte channel;
// to take care of diff element types in 1 array,
// since i can't cast on left-hand side of equation
[FieldOffset(5)]public byte [] dataBytePtr;
[FieldOffset(5)]public ushort [] dataUshortPtr;
[FieldOffset(5)]public uint [] dataUintPtr;
};
....
byte [] msg = new byte[256];
fixed(SERIAL_CAN_MSG_TYPE * msgPtr = (SERIAL_CAN_MSG_TYPE*) msg[0])
{
...
for(i = 0; i < 64; i++)
{
// assigns a ushort to the data array using ushort ptr
msgPtr->dataUshortPtr = spoolChannel.address;
}
...
}
----------- end c# code --------
above c# code produces error:
"Cannot take the address or size of a variable of a managed
type('SERIAL_CAN_MSG_TYPE')"
on the "fixed" line.
i've read that in c#, a pointer is not permitted to point to a struct
that contains references (arrays). i'm sure it has something to do
with managed/unmanaged code, but i don't understand it deep enough to
figure out a solution!
thanks for any help...
searched the web and after 2 days still cannot solve it. i am
converting a c++ application to c# - the problem code is listed below.
the c++ code uses a byte array (msg[256]) to hold a serial message.
since the message can be of different layouts, the array is cast to the
appropriate layout "type" (struct SERIAL_CAN_MSG_TYPE, in this
example). to complicate things, there is an array at the end of the
SERIAL_CAN_MSG_TYPE struct, data[], which can hold variable data types
(byte, ushort, and uint) -AND- can be of variable length (more than 2
elements). with that said, here's the c++ code:
---------- start c++ code -------------
typedef unsigned char INT_8U;
typedef unsigned short int INT_16U;
typedef short int INT_16;
....
typedef struct
{
INT_8U priority;
INT_16 dlc;
INT_8U messageType;
INT_8U channel;
INT_8U data[2];
}SERIAL_CAN_MSG_TYPE;
....
INT_8U msg[256];
SERIAL_CAN_MSG_TYPE* msgPtr;
msgPtr = (SERIAL_CAN_MSG_TYPE*)&(msg[0]);
....
// uses casting to assign a ushort to the byte array (data)
for(i = 0; i < 64; i++)
{
*((INT_16U *)&msgPtr->data[i*4]) = spoolChannel.address;
}
------- end c++ code --------
..... and here's my attempt at converting to c#:
----------- start c# code ------------
[StructLayout(LayoutKind.Explicit)]
unsafe public struct SERIAL_CAN_MSG_TYPE
{
[FieldOffset(0)]public byte priority;
[FieldOffset(1)]public short dlc;
[FieldOffset(3)]public byte messageType;
[FieldOffset(4)]public byte channel;
// to take care of diff element types in 1 array,
// since i can't cast on left-hand side of equation
[FieldOffset(5)]public byte [] dataBytePtr;
[FieldOffset(5)]public ushort [] dataUshortPtr;
[FieldOffset(5)]public uint [] dataUintPtr;
};
....
byte [] msg = new byte[256];
fixed(SERIAL_CAN_MSG_TYPE * msgPtr = (SERIAL_CAN_MSG_TYPE*) msg[0])
{
...
for(i = 0; i < 64; i++)
{
// assigns a ushort to the data array using ushort ptr
msgPtr->dataUshortPtr = spoolChannel.address;
}
...
}
----------- end c# code --------
above c# code produces error:
"Cannot take the address or size of a variable of a managed
type('SERIAL_CAN_MSG_TYPE')"
on the "fixed" line.
i've read that in c#, a pointer is not permitted to point to a struct
that contains references (arrays). i'm sure it has something to do
with managed/unmanaged code, but i don't understand it deep enough to
figure out a solution!
thanks for any help...