如何在C ++和C ++之间传递C#对象引用 [英] How to pass C# object references to and from C++
问题描述
是否可以通过本机互操作将C#对象引用(类类型,而不是结构)传入和传出C ++?
这是我的用例:
我正在尝试用C#编写游戏引擎,但想使用本机(C ++)物理库.物理库维护所有物理物体的内部状态,并允许用户将少量数据(指针)与每个物体关联.进行物理模拟勾号后,该库将提供所有移动的物理物体的列表.我想遍历此列表,并将所有更改中继到相应的C#对象.
问题是:将C#中的对象与C ++中相应的物理实体相关联的最佳方法是什么?
我可以想到几种方法:
- 为每个物理主体提供某种ID,在C ++中将其与物理主体相关联,并在C#中维护ID到对应对象的映射.即使使用优化的映射机制,这对我来说也不一定是间接的.
- 利用将C#委托(可以隐式引用C#对象实例)编组为C ++函数指针的功能.这可能是最好的方法.我不知道C#如何实现委托以及这将带来什么类型的开销.
- 找到其他方法来引用C ++中的C#对象,并将该引用与每个本机物理实体相关联.
是否存在我不知道的类似于选项3的机制?C ++/CLI不是一种选择,因为我想在没有它的情况下支持平台.
我建议使用专门针对此类情况设计的工具,例如 System.Runtime.InteropServices.GCHandle
.>
用法
在:
- 使用
GCHandleType.Normal
或GCHandleType.Weak
为您的CLR对象分配GCHandle
. - 通过
GCHandle.ToIntPtr
将GCHandle
转换为IntPtr
. - 将该
IntPtr
作为您提到的用户数据指针传递到C ++端.
出局:
- 从C ++端获取
IntPtr
. - 通过
GCHandle.FromIntPtr
将 - 使用
GCHandle
的Target
属性获取原始的CLR对象.
IntPtr
转换回 GCHandle
当不再从C ++端引用CLR对象时(由于C ++对象被破坏或由于将用户数据指针重置为例如 IntPtr.Zero
),请释放调用
GCHandle.Free
.
您应该分配哪种类型的 GCHandle
取决于您是否希望 GCHandle
使对象保持活动状态( GCHandleType.Normal
)( GCHandleType.Weak
).
Is there any way to pass C# object references (class types, not structs) into and out of C++ via native interop?
Here's my use case:
I'm trying to write a game engine in C# but want to use a native (C++) physics library. The physics library maintains its own internal state of all the physical bodies and lets the user associate a small amount of data (a pointer) with each body. After a physics simulation tick, the library supplies a list of all physical bodies that moved. I want to iterate over this list and relay all the changes to the corresponding C# objects.
The question is: what's the best way to associate objects in C# with the corresponding physical bodies in C++?
I can think of a couple ways:
- Give each physical body an ID of some kind, associate the ID with the physical body in C++, and maintain a map of ID's to corresponding objects in C#. This seems unnecessarily indirect to me, even with an optimized mapping mechanism.
- Take advantage of the ability to marshal C# delegates (which can implicitly reference C# object instances) into C++ function pointers. This might be the best way to do it; I don't know how C# implements delegates and what type of overhead this would entail.
- Find some other way to refer to C# objects in C++ and associate that reference with each native physical body.
Is there any mechanism like option 3 I don't know of? C++/CLI isn't an option since I want to support platforms without it.
I would suggest using the tool that was specifically designed for situations like that, i.e. System.Runtime.InteropServices.GCHandle
.
Usage
In:
- Allocate a
GCHandle
for your CLR object withGCHandleType.Normal
orGCHandleType.Weak
. - Convert the
GCHandle
to anIntPtr
viaGCHandle.ToIntPtr
. - Pass that
IntPtr
to the C++ side as the userdata pointer that you mentioned.
Out:
- Get
IntPtr
back from the C++ side. - Convert the
IntPtr
back to aGCHandle
viaGCHandle.FromIntPtr
- Use the
Target
Property of theGCHandle
to get to the original CLR object.
When the CLR object is no longer being referenced from the C++ side (either because the C++ object was destroyed or because you reset the userdata pointer to e.g. IntPtr.Zero
), release the GCHandle
by calling GCHandle.Free
.
What type of GCHandle
you should allocate depends on whether you want the GCHandle
to keep the object alive (GCHandleType.Normal
) or not (GCHandleType.Weak
).
这篇关于如何在C ++和C ++之间传递C#对象引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!