从托管代码调用C ++函数时出现异常

时间:2014-11-07 12:20:05

标签: c# interop

让我们想象一下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个字节的结构正常。另一方面,相同的函数但没有参数允许返回原始结构而无例外。

0 个答案:

没有答案