【发布时间】:2012-04-30 15:52:03
【问题描述】:
我需要将一个结构数组从 C++ 传递到 C#。我有下面的代码,它首先创建一个临时结构,然后将memcpy它到C#端结构的地址。我用相同的元素顺序定义了两边的结构。
当我调试时,我看到临时结构被正确填充,temp_buf(目标变量的地址)在每次迭代时结构的大小都会增加,memcpy 不会返回任何错误。
但是C#端只设置了数组的第一项。
以下是 C# 方面的定义:
[DllImport(@"MyAwesomeDLL.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?GetDevices@@YAHPAXIPAIPAUDEVICE_S@@@Z", CharSet = CharSet.Auto)]
public static extern Int32 GetCoolDevices(out UInt32 p_deviceCount, out Device_s p_devicesBuf);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct Device_s
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 51)]
public String DeviceName;
public UInt32 DeviceID;
}
以下是 C++ 方面的定义:
#pragma pack (1)
typedef struct
{
TCHAR device_name [51];
UINT32 device_rid;
} DEVICE_S;
int GetDevices (UINT32 *device_count, DEVICE_S *devices_buf)
{
....
while(....)
{
DEVICE_S tmp_device;
memset(&tmp_device, 0, sizeof(DEVICE_S));
tmp_device.device_id = 5;
sprintf( tmp_device.device_name, "a string");
DEVICE_S *temp_buf = &(devices_buf[i]);
size_t mysize = sizeof(DEVICE_S);
memcpy(temp_buf, &tmp_device, mysize);
i++;
getNextDevice();
}
.....
}
而且,我是这样称呼它的:
UInt32 MyDecDeviceCnt = 0;
Device_s[] MyDecDevices = new Device_s[10];
int ret = GetCoolDevices(out MyDecDeviceCnt, out MyDecDevices[0]);
欢迎提出任何建议!
【问题讨论】:
-
@SamFisher83 - 你的建议毫无意义。使用字符串是正确的过程。当然这两个结构的大小甚至不一样,C#结构至少要大12位。
-
@Ramhound 我纠正了我的拼写错误。现在,device_name 的长度为 51 个字符。还是不匹配?
标签: c# c++ marshalling