将包含struct的c ++函数传递给C#,并将其转换为带有Marshal.PtrToStructure的c#函数

时间:2013-08-28 18:47:21

标签: c# c++ marshalling extern

我对c ++很新,所以我可能在这方面有些错误。 所以我开始编写简单的C ++函数,它将包含struct作为返回类型:

我的c ++结构:

struct a {
   int i;
};

我在library.h文件中的c ++函数声明:

extern "C" __declspec(dllexport) struct a retNumber(); 

我在library.cpp文件中的c ++函数描述:

struct a retNumber()
{
   struct a r = a();
   r.i = 22;
   return r;
}

所以我只想编译它然后在c#代码中使用它,我得到以下编译错误:

error C2371: 'retNumber' : redefinition; different basic types
error C2526: 'retNumber' : C linkage function cannot return C++ class 
error C2556: 'a retNumber(void)' : overloaded function differs only by return type from 'void retNumber(void)'  

这是我问题的第一部分,如果你们帮我解决,我会非常感激,一旦它解决了,我将在我的c#代码中声明相同的结构:

struct a1
{
    int i;
}

然后我将导入我的c ++函数:

[DllImport("library.dll")]
public static extern a1 retNumber();

一旦完成,我将创建GCHandle:

a1 test = retNumber();
GCHandle handle = GCHandle.Alloc(test, GCHandleType.Pinned); 

然后我将尝试转换我的实际结果并释放内存:

        Object temp = Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(a1));
        handle.Free();

所以此时我应该拥有类型为a1的对象并包含值为22的变量i。

如果有人能通过这个过程取悦我,我会非常感激! 非常感谢你提前!!!

1 个答案:

答案 0 :(得分:1)

在C ++方面,您需要将所有内容都包装在extern "C"中,包括struct:

extern "C" {
    struct a {
       int i;
    };
};

在C#端,您需要正确指定调用约定:

[DllImport("library.dll", CallingConvention=CallingConvention.Cdecl))]
public static extern a1 retNumber();

一旦你这样做,就不需要Marshal.PtrToStructure电话。只是做:

a1 test = retNumber();
Console.WriteLine(a1.i); // Should print 22