【发布时间】:2011-02-09 11:15:01
【问题描述】:
C++
#define FIELD_SIZE_MSGID 24
#define FIELD_SIZE_TIME 12
#define FIELD_SIZE_ADMIN 256
typedef struct
{
char MsgId[FIELD_SIZE_MSGID+1];
char SendTime[FIELD_SIZE_TIME+1];
char ReceiptTime[FIELD_SIZE_TIME+1];
} AdminDataM0;
typedef struct
{
int Type;
union
{
AdminDataM0 M0;
char Data[FIELD_SIZE_ADMIN + 1];
} AdData;
char Unknown[FIELD_SIZE_ADMIN + 1];
} AdminData;
C#:
[DllImport("Receiver.dll",
CallingConvention = CallingConvention.Cdecl,
ExactSpelling = false,
SetLastError = false,
CharSet = CharSet.Ansi,
EntryPoint = "SendMessage")]
[return: MarshalAs(UnmanagedType.I4)]
protected static extern int SendMessage(
[MarshalAs(UnmanagedType.Struct)] ref AdminData ptrAdminData,
);
protected const Int32 FIELD_SIZE_MSGID = 24;
protected const Int32 FIELD_SIZE_TIME = 12;
protected const Int32 FIELD_SIZE_ADMIN = 256;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct AdminDataM0
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = FIELD_SIZE_MSGID + 1)]
public char[] MsgId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = FIELD_SIZE_TIME + 1)]
public char[] SendTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = FIELD_SIZE_TIME + 1)]
public char[] ReceiptTime;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
protected struct AdminData
{
[MarshalAs(UnmanagedType.I4)]
public Int32 nType;
[MarshalAs(UnmanagedType.Struct)]
public Data AdminData_Data;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct Data
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.Struct)]
public AdminDataM0 M0; //135
[FieldOffset(0)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = FIELD_SIZE_ADMIN + 1)]
public char[] Data_FldSizeAdmin;
}
[MarshalAs(UnmanagedType.ByValArray, SizeConst = FIELD_SIZE_ADMIN + 1)]
public char[] Unknown;
}
主要:
AdminData oAdminData = new AdminData();
oAdminData.AdminData_Data = new oAdminData.Data();
oAdminData.AdminData_Data.M0 = new oAdminDataM0();
oAdminData.AdminData_Data.M0.MsgId = new char[FIELD_SIZE_MSGID + 1];
oAdminData.AdminData_Data.M0.SendTime = new char[FIELD_SIZE_TIME + 1];
oAdminData.AdminData_Data.M0.ReceiptTime = new char[FIELD_SIZE_TIME + 1];
oAdminData.AdminData_Data.Data_FldSizeAdmin = new char[FIELD_SIZE_ADMIN + 1];
oAdminData.Unknown = new char[FIELD_SIZE_ADMIN + 1];
string M0_MsgId = "MsgId";
string M0_SendTime = "Send Time";
string M0_ReceiptTime = "ReceiptTime";
string unknown = "Unknown";
M0_MsgId.ToCharArray().CopyTo(oAdminData.AdminData_Data.M0.MsgId, 0);
M0_SendTime.ToCharArray().CopyTo(oAdminData.AdminData_Data.M0.SendTime, 0);
M0_ReceiptTime.ToCharArray().CopyTo(oAdminData.AdminData_Data.M0.ReceiptTime, 0);
// function to DLL
SendMessage(ref oAdminData);
问题:
只有 MsgId 和 DataData_FldSizeAdmin 具有相同的值。 我认为这是因为它们共享相同的内存地址。
UNKNOWN、SENDTIME 和 RECEIPTIME 没有值。
【问题讨论】:
-
我已经在 c# 中尝试过这些,但我相信仍然缺少...我将 [FieldOffset(0)] 用于内部结构的两个成员变量,因为它是 c++ 中的联合。跨度>
-
这是在什么平台上的?您是否在同一平台上保存和加载数据?您必须小心注意不同平台上的不同对齐方式。
-
谢谢史蒂夫!对!我在 WinXP 上运行它。
-
Steve 你所说的对齐是什么意思?对不起,我还是 c# 的新手。
-
当一个 C# 结构被编组时,它会生成一个字节块。字节数组中 C# 结构的每个成员的位置在不同平台上可能会有所不同,因此您有时需要调整编组生成字节数组的方式,以使其在两个平台上的工作方式相同。
标签: c# c++ interop marshalling