在托管包装器中包装非托管C ++ [英] Wrapping unmanaged c++ in a managed wrapper

查看:76
本文介绍了在托管包装器中包装非托管C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个不受管理的C ++库.我想公开.NET应用程序的功能.我不确定该如何处理其中的一种功能:

I have an unmanaged C++ library. I would like to expose the functionality for .NET applications. There's one partucular function I am not sure how to handle:

typedef void(free_fn *)(void *); 无效放置(void * data,free_fn deallocation_function);

typedef void (free_fn*) (void*); void put (void *data, free_fn deallocation_function);

这个想法是您将动态分配的缓冲区传递给该函数并提供一个释放函数.该库将异步处理数据,并在以后不再需要数据时释放缓冲区:

The idea is that you pass dynamically allocated buffer to the function and supply a deallocation function. The library will process the data asynchronously and will release the buffer later on when data is no longer needed:

无效* p = malloc(100); ...填写缓冲区... 放(p,免费);

void *p = malloc (100); ... fill in the buffer... put (p, free);

我该如何向.NET应用程序公开这种东西?

How can I expose this kind of thing to .NET applications?

推荐答案

执行此操作时请务必小心. .NET确实非常希望将其对象固定在非托管例程中,并在输出时固定.如果您的非托管代码保留了一个指针值(该指针值已固定在该指针值上),那么很有可能会移动内存或进行垃圾回收,或者同时发生这两种情况.

Be very careful when you do this. .NET really, really wants to have its objects be pinned on the way into an unmanaged routine and unpinned on the way out. If your unmanaged code holds onto a pointer value, that had been pinned on the way in then there is very real chance that the memory will be moved or garbage collected or both.

在将委托编组为函数指针的情况下尤其如此(请相信我-我发现被封送的委托正在我身上被垃圾回收-我让Microsoft的人为我验证了这一点).解决此问题的最终方法是将代表的副本存放在与唯一事务ID配对的静态表中,然后创建一个非托管函数,该函数在调用时通过事务ID在表中查找代表,然后执行该委托.这很丑陋,如果我还有其他选择,我会用的.

This is especially the case with delegates marshalled to function pointers (trust me on this - I found that marshaled delegates were being garbage collected on me - I had people at Microsoft verify that for me). The ultimate solution to this problem is to stash away copies of your delegates in a static table paired with a unique transaction id, then create an unmanaged function that when called looks up the delegate in the table via transaction id then executes it. It's ugly and if I had another choice, I would've used it.

这是在您的情况下执行此操作的最佳方法-由于您的非托管代码使用了它的设置而忘记了它的模型,那么您应该使API更加块化.在托管C ++中创建一个包装器,该包装器通过非托管例程分配内存,将数据复制到其中,然后将其与指向非托管解除分配器的指针一起传递.

Here's the best way to do this in your case - since your unmanaged code uses a set it and forget it model, then you should make your API chunkier. Create an wrapper in managed C++ that allocates memory via an unmanaged routine, copies your data into it and then passes it on along with a pointer to an unmanaged deallocator.

这篇关于在托管包装器中包装非托管C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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