如何将结构数组从 c++ 传递到 c#?
Posted
技术标签:
【中文标题】如何将结构数组从 c++ 传递到 c#?【英文标题】:How to pass an array of structs from c++ to c#? 【发布时间】:2020-01-27 06:51:10 【问题描述】:我已经研究了一段时间,但找不到解决方案。
我正在编写一个使用 c++/CLI 包装器的程序。我现在的目标是将所有正在运行的进程及其 PID(以及其他信息)的列表返回给 c#。我有一个正在运行的 C++ 函数,它返回一个 PROCESSENTRY32 类型的向量,但丝毫不知道如何将该信息传递给 c#。
我知道 c# 中有一个函数可以获取所有正在运行的进程,但我正在尝试在 c++ 中执行此操作。
任何正确方向的提示或指示都会很棒。
【问题讨论】:
也许可以试试 SWIG (swig.org)。我从来没有将它用于 C#,但它确实让 Java 的事情变得更容易。 具体来说,SWIG 的“Directors”功能允许本地代码轻松调用 C#。 您可以将您的 C++ 代码编译为程序集,并在您的 C# 代码中引用该程序集。请注意,从 C# 访问 C++ 内存可能会导致内存泄漏。 创建一个 C++ 包装器,将您的向量转换为 .net 类型。您没有展示任何代码,但任何有关 .net 和 C++ 的基本教程都会向您展示如何创建 .net 类型 【参考方案1】:首先,为您的 c# 应用程序设置一个 api 来访问数据。在您的 C++ 函数返回类型之前使用 __declspec(dllexport)
声明您的 API 函数。为此使用#define 会很方便。
在 C# 领域,确保您使用了 System.Runtime.InteropServices;
然后,为您的 api 使用 [DllImport("dll_name.dll", CharSet = CharSet.Unicode)]
方法属性为您的方法创建一个静态方法句柄,然后 static extern returnType CallCPPFunction();
您必须使用它编写一个自定义数据解析器方法,因为返回的数据只是一堆字节(意思是 C# 将尝试将从 C++ 接收到的数据转换为您在 C# 中指定的返回类型)。您可以在 C# 中创建一个使用字节数组构造的结构,并将其设置为构造函数参数,但是,您可以通过将一个或多个 int*
作为参数发送到保存有用数据的 C# 函数来简化工作,例如sizeof(object)
或对象数据中的重要标记,以使解析更容易。请记住,这里的内存同时由 C# 和 C++ 管理,所以如果你传递一个 int*
持有 sizeof(object)
你仍然需要在 C++ 中 delete
那个指针,但请确保你不要做任何事情就像 C# 或 C++ 仍在使用数据时那样。您可以在 C# 中编写一些 unsafe
代码,其中 C++ 传递一个以 false 开头的 bool*,然后 C# 在读取数据完成后将其标记为 true。
我不是编组业务方面的专家,但我过去曾成功使用过这种精确的数据传输方法。完全有可能在 C# 中有某种方法可以使用 C++ 类型,这样就不需要进行这种数据解析,或者 C# 以某种方式使用 .h 文件来做一些事情,但如果有的话,我不知道。这是我自己观看的用于弄清楚这个概念的教程,但它有点长,我找不到另一个与我正在寻找的东西相同的教程:
https://www.youtube.com/watch?v=w3jGgTHJoCY
如果我没记错的话,如果您在 C# 中重新创建 C++ 结构,这样定义的第一个数据成员是 C# 结构中相同的关联数据成员,第二个 C++ 成员,则甚至不需要数据解析到 C# 中的第二个等。请记住数据类型的大小需要匹配,否则一旦遇到 C++ 和 C# 中大小不匹配的数据成员,数据就会被偏移。如果您的结构包含子类型,您也需要在 C# 中重新创建它们;一直到原始类型级别。
【讨论】:
【参考方案2】:例如将vector更改为新列表,当vector的大小或值发生更改时,通知c#代码通知更新列表项(也许您可以使用事件来通知),这样可以解决您的问题吗?
【讨论】:
以上是关于如何将结构数组从 c++ 传递到 c#?的主要内容,如果未能解决你的问题,请参考以下文章