【发布时间】:2015-11-13 07:39:22
【问题描述】:
有没有办法通过本机互操作将 C# 对象引用(类类型,而不是结构)传入和传出 C++?
这是我的用例:
我正在尝试用 C# 编写游戏引擎,但想使用本机 (C++) 物理库。物理库维护自己的所有物理体的内部状态,并让用户将少量数据(指针)与每个体关联。在物理模拟滴答之后,库提供所有移动的物理实体的列表。我想遍历这个列表并将所有更改传递给相应的 C# 对象。
问题是:将 C# 中的对象与 C++ 中相应的物理实体关联的最佳方法是什么?
我能想到几种方法:
- 为每个物理体指定某种 ID,将 ID 与 C++ 中的物理体相关联,并在 C# 中维护 ID 到相应对象的映射。这对我来说似乎是不必要的间接,即使使用优化的映射机制。
- 利用将 C# 委托(可以隐式引用 C# 对象实例)编组为 C++ 函数指针的能力。这可能是最好的方法;我不知道 C# 如何实现委托以及这会带来什么类型的开销。
- 找到其他方法来引用 C++ 中的 C# 对象并将该引用与每个本机物理体相关联。
有没有我不知道的选项 3 之类的机制? C++/CLI 不是一个选项,因为我想支持没有它的平台。
【问题讨论】:
-
如果没有 C++/CLI 选项,P/Invoke 是接下来要考虑的事情。尽管通过 P/invoke 引用 c# 对象实际上是不可能的,并且委托也可能很难或不可能。但也许你可以从中得到一些东西。
-
是的,P/Invoke 就是我说“本机互操作”时的意思;我没有意识到它有一个名字。使用 P/Invoke 将 C# 委托作为函数指针传递给 C++ 是完全可行的,我只是不知道它有什么样的开销。 msdn.microsoft.com/en-us/library/367eeye0.aspx
-
找到另一个答案,描述了代表的一些(感知的)性能特征。 stackoverflow.com/a/2082975 也许使用它们是实现这一点的最佳方式。在 C++ 中迭代更改的主体列表时,只需为每个主体调用一个对应的委托,即可将新数据导入 C#-land。
-
Pinvoke 走错了路,有助于从 C# 调用本机代码,但反之则不行。让本机 C++ 了解外部类型系统以跨平台的方式看起来是什么样子是不可能的。微软在 COM 和 C++/CX 方面做得很好,但 *nix 的人不会与它有任何关系。不是在那里发明的。
-
C++ 代码实际上并不需要了解 C# 类型系统的任何信息;在这种情况下,它可以返回到 C# 的不透明指针将完成这项工作。只是说“嘿,你知道你告诉我的那件事吗?”我想它只是因为垃圾收集和重定位而不可用。