如何正确地将这些转换为c#,marshall,以便将这些结构传递给DLL(c+;+;)?
C++ C#: 主要内容: 问题: 只有MsgId和DataData_FldSizeAdmin具有相同的值。 我认为这是因为它们共享相同的内存地址如何正确地将这些转换为c#,marshall,以便将这些结构传递给DLL(c+;+;)?,c#,c++,interop,marshalling,C#,C++,Interop,Marshalling,C++ C#: 主要内容: 问题: 只有MsgId和DataData_FldSizeAdmin具有相同的值。 我认为这是因为它们共享相同的内存地址 未知、SENDTIME和ReceiptTime没有值。在结构声明中应使用MashalAs[UnmanagedType.ByValtString]而不是MarshalAs[UnmanagedType.ByValtString]: 例如: AdminData oAdminData = new AdminData(); oAdminData.AdminD
未知、SENDTIME和ReceiptTime没有值。在结构声明中应使用
MashalAs[UnmanagedType.ByValtString]
而不是MarshalAs[UnmanagedType.ByValtString]
:
例如:
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);
见:
ByValTStr:用于串联,
固定长度的字符数组
出现在一个结构中。这个
ByValTStr使用的字符类型为
由
System.Runtime.InteropServices.CharSet
政府的论据
System.Runtime.InteropServices.StructLayoutAttribute
应用于包含结构。
始终使用
MarshalAsAttribute.SizeConst字段
指示数组的大小
.NET Framework ByValTStr类型的行为
与C样式一样,固定大小的字符串
结构内部(例如,char
s[5])。托管代码中的行为
与Microsoft Visual Studio不同
基本6.0行为,不为空
终止(例如,MyString As
字符串*5)
“ByValArray”sais(重点矿山)的文件:
设置MarshalAsAttribute.Value时
要创建ByValArray,SizeConst必须为
设置以指示元素的数量
在数组中数组子类型字段
可以选择包含
数组元素的非托管类型
什么时候需要区分
在字符串类型中。你只能使用
此非托管类型位于
在结构中显示为字段。
因此,我认为要使您的代码使用
ByValArray
,您还应该在Marshallas
属性中添加ArraySubType
。我在c中尝试过这些,但我相信仍然缺少。。。对于内部结构的两个成员变量,我使用[FieldOffice(0)],因为它是C++中的一个联合。您是否在同一平台上保存和加载数据?你必须小心在不同的平台上寻找不同的路线。谢谢史蒂夫!是的!我在WinXP上运行这个。Steve你说的对齐是什么意思?抱歉,我还是c#的新手。当对c#struct进行封送处理时,它会生成一个字节块。字节数组中C#struct的每个成员在不同平台上的位置可能不同,因此有时需要调整编组生成字节数组的方式,使其在两个平台上的工作方式相同。@Ryan:btw,您可以在这里接受关于堆栈溢出的答案。。。甚至投票也是可能的;-)
[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);
...
public struct AdminDataM0
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FIELD_SIZE_MSGID + 1)]
public string MsgId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FIELD_SIZE_TIME + 1)]
public string SendTime;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FIELD_SIZE_TIME + 1)]
public string ReceiptTime;
}
...