让我们想象一下DLL中的C ++函数:
typedef struct
{
int number;
void *list;
} clist_t;
extern "C" DLL_API clist_t GetItems(int a);
DLL_API clist_t GetItems(int a)
{
static clist_t list;
list.number = a;
list.list = sth();
return list;
}
调用此函数的C#代码:
[StructLayout(LayoutKind.Sequential)]
public struct CList
{
public int number;
public IntPtr ptr;
};
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate CList GetItemsDelegate(int a);
int func = Win32APIWrapper.GetProcAddress(m_dllHndl, "GetItems");
private GetItemsDelegate GeItemsFunc =
(GetItmsDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)func, typeof(GetItemsDelegate));
CList list = GetItemsFunc(12); // <--- here we got exception
最后一个函数抛出异常:&#34;尝试读取或写入受保护的内存。这通常表明其他内存已损坏。&#34;
我注意到删除 CList 函数中的第二个字段会导致异常消失,并且返回的struct具有正确的 number 字段值。
那么为什么原始代码不起作用?结构的对齐似乎是正确的。调用约定也正确设置为 cdecl 。
有什么想法吗? struct中的两种类型都是blittable,所以甚至不需要编组它们(C#和dll编译为32位)。
修改
为什么返回较小的struct不会抛出异常?我注意到返回的小于4个字节的结构正常。另一方面,相同的函数但没有参数允许返回原始结构而无例外。