将包含结构的 c++ 函数传递给 C#,并使用 Marshal.PtrToStructure 将其转换为 c# 函数

Posted

技术标签:

【中文标题】将包含结构的 c++ 函数传递给 C#,并使用 Marshal.PtrToStructure 将其转换为 c# 函数【英文标题】:pass c++ function that contains struct to C# and convert it to c# function with Marshal.PtrToStructure 【发布时间】:2013-08-28 18:47:20 【问题描述】:

我对 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 的对象。

如果任何人都可以通过这个过程进行延迟,我将不胜感激! 非常感谢您提前!!!

【问题讨论】:

我真的建议,如果您有 2 个问题,请分别提出。 它们相互依赖,c++ 的人将能够看到我在寻找什么 【参考方案1】:

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

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

【讨论】:

感谢 Reed 的回答,如果您能简要说明在哪些情况下我需要使用 Marshal.PtrToStructure 会很棒,谢谢 好吧,所以我包装了结构,但是编译器仍然抱怨我的函数: struct a retNumber() struct a r = a(); r.i = 22;返回 r; @Stanislav 尝试使用 typedef 进行 hte 结构声明。

以上是关于将包含结构的 c++ 函数传递给 C#,并使用 Marshal.PtrToStructure 将其转换为 c# 函数的主要内容,如果未能解决你的问题,请参考以下文章

如何将 C++ 对象传递给 C# 类库

将 C++ 对象传递给 C#

将 C# 对象(包含静态对象成员)作为参数传递给 C++/CLI 程序

c++ 在创建时将构造函数参数从父对象传递给子对象

将 C# 数据类型参数传递给用 C++ 编写的 dll?

将 Json 复杂对象传递给 HttpPost 调用