【问题标题】:Preserving C++ / CLI handles to .NET objects in C library calls在 C 库调用中保留 .NET 对象的 C++/CLI 句柄
【发布时间】:2012-04-10 15:59:46
【问题描述】:

我有一个 C# 库,需要用作直接 C Win32 应用程序的一部分。我正在尝试在 C++ / CLI 中编写一个可以处理 C# .NET 对象的包装器。唯一的问题是整个项目不能用 C++ 编译,它必须留在 C 中。

为了解决这个问题,我想将我的 C# 对象的实例不透明地传递回 C 代码,以便它们可以传入并在包装库调用中使用,但我不知道该怎么做。例如,我想做这样的事情:

C++/CLI 包装器:

void * ReturnObject(char *name){
  return (void *)gcnew MyObject(gcnew String(name));
}

void UseObject (void *object){
  MyObject ^handle = (MyObject ^)object;
  object -> use();
}

使用 C++ 静态库的原生 C 代码:

int main (char **argv){
  void *obj = ReturnObject("foobar");
  UseObject(obj);
}

所以 C 代码从不关心 obj 的内容是什么,甚至不知道 CLR 类型 MyObject,但它只是传递数据以保持对象持久性。我认为这应该使用void 指针来完成,但 C++ 编译器不想进行强制转换。我不知道这是否是因为托管内存和非托管内存之间的差异,或者我只是没有正确执行此操作,但我当然会感谢任何帮助。

所以,回顾一下: 我正在尝试在 C++/CLI 包装库中实例化 .net 对象,并将这些对象保存在直接 C 代码中,以便它们可以在我尚未编写的其他 C++/CLI 库调用中再次使用。

有什么建议吗?

【问题讨论】:

    标签: c# c c++-cli clr


    【解决方案1】:

    您不能将句柄存储在 void* 中,因为垃圾收集器可以移动对象,使指针变得比无用更糟糕(它现在将指向其他一些随机对象)。

    您需要使用 C++/CLI 提供的gcroot 模板。然后您可以将gcroot<MyObject>* 存储到void* 中并将其传递给您的C 代码。完成后不要忘记正确释放 gcroot,以运行析构函数。

    您还可以查看 GCHandle 类,它是 .NET 类库的一部分。但在 C++/CLI 代码中推荐使用gcroot(它在内部使用GCHandle)。

    【讨论】:

    • 好的,我想我已经搞定了,但现在我不知道如何调用对象上的方法。这是我所拥有的:gcroot<myObject^>* handle = (gcroot<myObject^>*) object; 其中object 作为空指针传入。我现在如何访问对象的方法和成员?当我像使用常规句柄一样尝试 handle -> someMethod() 时,编译器只是说 someMethod 不是 gcroot 的成员。
    • @Drewmate:你需要(*handle)->someMethod()
    猜你喜欢
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多