我有一个用C ++开发的dll。我需要在C#中使用它。
[StructLayout(LayoutKind.Sequential, Size = 205004, Pack = 1)]
private struct MyList
{
public UInt32 count;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public myStruct[] info;
};
" MYSTRUCT"的尺码是2050。 我将dll方法称为
[DllImport("dllName.dll" CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GetMyList(out MyList list);
调用dll方法时出错。 "无法编组'参数#1':内部限制:结构太复杂或太大。"
通过不更改C ++ dll部分,是否有人有解决方案?
答案 0 :(得分:1)
正如错误所说,结构太大而无法通过这种方式进行编组。所以你必须找到另一种方法。
在我看来,一次一个地返回结构会更有意义。这将避免您需要硬编码列表中不超过100个结构的上限。
所以我会这样写:
<强> C ++ 强>
int GetListCount()
{
return count;
}
int GetListItem(int index, myStruct* item)
{
if (index < 0)
return -1;
if (index >= count)
return -1;
*item = items[index];
return 0;
}
<强> C#强>
[DllImport("dllName.dll" CallingConvention = CallingConvention.Cdecl)]
private static extern int GetListCount();
[DllImport("dllName.dll" CallingConvention = CallingConvention.Cdecl)]
private static extern int GetListItem(int index, out myStruct item);
....
int count = GetListCount();
myStruct[] items = new myStruct[count];
for (int index = 0; index < count; index++)
{
int retval = GetListItem(out items[index]);
if (retval != 0)
// handle error
}
如果您无法更改DLL,那么您将面临手动执行编组操作。它会是这样的:
[DllImport("dllName.dll" CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GetMyList(IntPtr listPtr);
....
IntPtr listPtr = Marshal.AllocHGlobal(205004); // Argh! Magic constant alert
try
{
int retval = GetMyList(listPtr);
// presumably you are expected to do something with retval
int count = Marshal.ReadInt32(listPtr);
myStruct[] items = new myStruct[count];
for (int index = 0; index < count; index++)
{
IntPtr itemPtr = listPtr + 4 + index*2050; // More magic constants!
items[index] = (myStruct)Marshal.PtrToStructure(itemPtr, typeof(myStruct));
}
}
finally
{
Marshal.FreeHGlobal(listPtr);
}
您可能更喜欢使用Marshal.SizeOf
而不是魔术常量。