将CLR类型强制转换为void *并返回 [英] Casting a CLR type to void* and back

查看:414
本文介绍了将CLR类型强制转换为void *并返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何正确转换CLR类型,例如 Foo ^ void * ,然后返回一段时间?

How to properly convert a CLR type, say Foo^, to void* and back some time later?

这种情况是,我在DLL中有一些非托管代码,可以总结为

The scenario is, I have some unmanaged code in a DLL that can be summarized as

class Handler {
  void* _obj;
  void (*_call)(void* obj, int detail);

  void handle_event() { _call(_obj, 1234); }
public:
  void set_object(void* obj) { _obj = obj; }
  void set_callback(void(*callback)(void*,int)) { _call = callback; }
};

我想将一个CLR对象存储在 Handler _obj 字段。如何实现它,考虑到GC可能移动CLR对象? ( pin_ptr gcroot ?)

I want to store a CLR object in the Handler's _obj field. How to implement it, taking into account that the GC may move the CLR object? (pin_ptr? gcroot?)

static void event_callback(void* obj, int detail) {
   Foo^ clr_obj = undo_magic(obj);
//                ^^^^^^^^^^ how?
   clr_obj->DoStuff(detail);
}

public ref class Foo {
   Handle* h;
public:
   void Start() {
     h = new Handler;
     void* obj = do_magic(this);
//               ^^^^^^^^ how?
     h->set_object(obj);
     h->set_callback(event_callback);
   }
   ...
}


推荐答案

需要固定。但是,您正在存储此引用,要求对象保持固定。这是相当不健康,垃圾收集器将不断地工作周围。另一个问题是,只是钉住是不够的,必须有一个可识别的对象引用,以便GC不会收集对象。存储的void *不够好。你通常会使用gcroot<>来解决这个问题,但这在这里也不行。

Pinning would be required. However, you are storing this 'reference', requiring the object to stay pinned. That's quite unhealthy, the garbage collector would constantly have to work around it. Another problem is that just pinning isn't enough, there has to be a recognizable reference to the object so that the GC won't collect the object. The stored void* isn't good enough. You'd normally solve this with gcroot<> but that can't work here either.

一个更好的方法是简单地传递一个句柄。使用字典< int,Foo ^> 将void *转换回对象。或者 List< Foo ^> ,现在索引可以是句柄。

A better approach is to simply pass a 'handle'. Use a Dictionary<int, Foo^> to convert the void* back to the object. Or a List<Foo^>, now the index could be the handle.

这篇关于将CLR类型强制转换为void *并返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆