我做了一些C#互操作工作。 我有以下结构:
#pragma pack(push,1)
typedef struct
{
unsigned __int64 Handle;
LinkType_t Type;
LinkState_t State;
unsigned __int64 Settings;
signed __int8 Name[MAX_LINK_NAME];
unsigned __int8 DeviceInfo[MAX_LINK_DEVINFO];
unsigned __int8 Reserved[40];
} LinkInfo_t;
这是我尝试将其转换成一个C#的结构:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct LinkInfo_t
{
[MarshalAs(UnmanagedType.U8)]
public UInt64 Handle;
MarshalAs(UnmanagedType.I4)]
public LinkType_t Type;
[MarshalAs(UnmanagedType.I4)]
public LinkState_t State;
[MarshalAs(UnmanagedType.U8)]
public UInt64 Settings;
[MarshalAs(UnmanagedType.LPStr, SizeConst = MAX_LINK_NAME)]
public string Name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_LINK_DEVINFO, ArraySubType = UnmanagedType.U1)]
public byte[] DeviceInfo;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40, ArraySubType = UnmanagedType.U1)]
public byte[] Reserved;
}
但是,每当我初始化结构的名称,DeviceInfo,并保留字段都设置为null。 我该如何解决?
对于数组,尽量使用fixed
关键字:
public fixed byte DeviceInfo[MAX_LINK_DEVINFO];
public fixed byte Reserved[40];
每当我初始化结构的名称,DeviceInfo,并保留字段都设置为null
这是正确的,你的定义看起来OK我(顺便说一句,你不需要[MarshalAs]
在原始字段的默认行为是你指定什么有做的)。 因为你的阵列字段null
,编组你的结构非托管内存时,封送什么都不会做他们,但它要创建的字符串,解编时阵列。
什么安东Tykhyy说是正确的。 我只是想用一些例子来阐明。 使用“固定”的作品,但强迫你使用“不安全”为好。 我想避免使用不安全尽可能。 使用元帅是一个办法让周围。
首先,让我们说,我有一个用C以下定义创建的库。
typedef struct {
int messageType;
BYTE payload[60];
} my_message;
/**
* \param[out] msg Where the message will be written to
*/
void receiveMessage(my_message *msg);
/*
* \param[in] msg The message that will be sent
*/
void sendMessage(my_message *msg);
在C#,以下结构将等效于一个在C.
[StructLayout(LayoutKind.Sequential, Size = 64), Serializable]
struct my_message
{
int messageType;
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 60)]
byte[] payload;
public initializeArray()
{
//explicitly initialize the array
payload = new byte[60];
}
}
由于receiveMessage味精()记录为[OUT],你不需要把它传递给函数之前做什么特别在结构数组。 即:
my_message msg = new my_message();
receiveMessage(ref msg);
byte payload10 = msg.payload[10];
由于的sendMessage味精()记录为[中],则需要调用函数之前,填补了数组。 填充阵列之前,该阵列需要使用它之前被明确实例化。 即:
my_message msg = new my_message();
msg.initializeArray();
msg.payload[10] = 255;
sendMessage(ref msg);
调用initializeArray()应该实例在结构这个阵列中创建以前分配的空间阵列。