首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将C#对象引用传递给C++

如何将C#对象引用传递给C++
EN

Stack Overflow用户
提问于 2015-08-19 20:29:44
回答 2查看 3.9K关注 0票数 5

是否有任何方法通过本机互操作将C#对象引用(类类型,而不是结构)传入和输出C++?

这里是我的用例:

我试图用C#编写一个游戏引擎,但想使用本地(C++)物理库。物理库维护所有物理体的内部状态,并允许用户将少量数据(指针)与每个体相关联。在进行了物理模拟之后,这个库提供了所有移动的物理物体的列表。我想迭代这个列表,并将所有更改转发到相应的C#对象。

问题是: C#中的对象与C++中相应的物理体相关联的最佳方法是什么?

我可以想出几种方法:

  1. 为每个物理体提供某种ID,将ID与C++中的物理体关联起来,并维护ID到C#中相应对象的映射。对我来说,这似乎是不必要的间接,即使使用优化的映射机制也是如此。
  2. 利用将C#委托(可以隐式引用C#对象实例)封送到C++函数指针的能力。这可能是最好的方法;我不知道C#是如何实现委托的,也不知道这会带来什么样的开销。
  3. 找到在C#中引用C++对象的其他方法,并将该引用与每个本机物理体相关联。

有没有像选项3这样的机制我不知道?C++/CLI不是一个选项,因为我想支持没有它的平台。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-20 01:43:35

我建议使用专门为这种情况而设计的工具,即System.Runtime.InteropServices.GCHandle

使用

在:

  1. 使用GCHandleGCHandleType.Normal为CLR对象分配一个GCHandleType.Weak
  2. 通过GCHandleIntPtr转换为GCHandle.ToIntPtr
  3. 将该IntPtr作为您提到的userdata指针传递到C++端。

退出:

  1. IntPtr从C++那边回来。
  2. 通过IntPtrGCHandle转换回GCHandle.FromIntPtr
  3. 使用Target属性的GCHandle获取原始的CLR对象。

当不再从C++端引用CLR对象时(或者因为C++对象被破坏,或者因为您将用户数据指针重置为例如IntPtr.Zero),则通过调用GCHandle.Free释放GCHandle

您应该分配哪种类型的GCHandle取决于您是否希望GCHandle保持对象活动(GCHandleType.Normal) (GCHandleType.Weak)。

票数 6
EN

Stack Overflow用户

发布于 2015-08-19 21:22:33

  1. 映射唯一标识符将允许您将托管代码与非托管代码隔离开来。如果非托管方没有对您的托管对象做任何事情,可能会更好,因为您实际上无法控制对象生命周期的大部分。
  2. 作为函数指针的委托是可能的。您所需要做的就是定义委托类型并创建一个实例。然后,您可以使用Marshal.GetFunctionPointerForDelegate获取要传递给非托管端的地址。唯一要注意的是,您必须确保回调使用的是__stdcall
  3. 可能可以直接访问类成员和函数,但如果没有C++/CLI包装器,您就会使用fire。
  4. 在C#端分配一块内存,并将其传递给C++。在托管端的类中,使用属性访问具有适当偏移量的内存。
  5. 使对象COM可见

另外,请记住,AccessViolationException在.NET中通常是不可捕捉的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32105089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档