C 库的 C++/CLI 类包装器 - 回调
我正在使用 C++/CLI 包装 C 库。 C 库设计为从非托管 C++ 类中使用。这意味着库函数接受 C++ 对象指针,然后在回调中提供该指针。这使得回调代码能够将请求重定向到调用 C++ 对象中的适当事件函数。
实际函数非常复杂,因此我将问题空间简化为几个基本项:
// C library function signature
void CLibFunc(CLIBCALLBACK *callback, void *caller);
// C callback signature
// Second parameter is meant to point to the calling C++ object
typedef int (__stdcall CLIBCALLBACK) (int param1, void *caller);
// C callback implementation
int CallBackImpl(int param1, void* caller)
{
// Need to call the ManagedCaller's EventFunction from here
// ???
}
// C++/CLI caller class
public ref class ManagedCaller
{
public:
void CallerFunction(void)
{
// Call the C library function
// Need to pass some kind of this class pointer that refers to this object
CLibFunc(CallBackImpl, ????);
}
void EventFunction(param1)
{
}
}
现在需要从托管 C++ 类调用 C 库函数。在 C++/CLI 下,垃圾收集器在内存中移动对象,因此向类传递简单的固定指针不再起作用。我可以通过固定对象来解决问题,但不建议这样做,因为它会导致内存碎片。似乎另一个选择是使用 auto_gcroot 指针,但我对托管 C++ 相当陌生,我不知道如何完成这项工作。
有谁知道如何进行这项工作?应该将什么样的指针传递给 C 函数?回调实现应该如何重定向到调用对象的事件函数?
I am wrapping a C library using C++/CLI. The C library was designed to be used from an unmanaged C++ class. This means that the library functions accept a C++ object pointer and then provide that pointer back in callbacks. This enables the callback code to redirect requests to an appropriate event function in the calling C++ object.
The actual functions are quite involved, so I have simplified the problem space to just a few basic items:
// C library function signature
void CLibFunc(CLIBCALLBACK *callback, void *caller);
// C callback signature
// Second parameter is meant to point to the calling C++ object
typedef int (__stdcall CLIBCALLBACK) (int param1, void *caller);
// C callback implementation
int CallBackImpl(int param1, void* caller)
{
// Need to call the ManagedCaller's EventFunction from here
// ???
}
// C++/CLI caller class
public ref class ManagedCaller
{
public:
void CallerFunction(void)
{
// Call the C library function
// Need to pass some kind of this class pointer that refers to this object
CLibFunc(CallBackImpl, ????);
}
void EventFunction(param1)
{
}
}
Now the C library functions need to be called from a managed C++ class. Under C++/CLI, the garbage collector moves objects around in memory, so passing a simple fixed pointer to the class does not work anymore. I can solve the problem by pinning the object, but that is not recommended because it leads to memory fragmentation. It seems that another option would be to use auto_gcroot pointers, but I am fairly new to managed C++ an I am not sure how to make this work.
Does anyone know how to make this work? What kind of pointer should be passed to the C function? How should the callback implementation redirect to the calling object's event function?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这恰好与我现在正在做的事情相似。
以下是关于使用 C++ 类提供本机回调的博客文章: http://blogs.microsoft.co.il/blogs/alon/archive/2007/05/29/Native-Callback.aspx
我不熟悉从 C 调用 C++ 成员函数,但我已经为另一个 C++ 类做了一个接口(抽象基)类以进行回调(类似于本文)。下面是我提供桥的一个基本示例:
现在,为了使其可用于提供程序的托管实现,我们必须创建一系列提供桥的类。
编辑:添加了代码来显示我使用的托管接口类示例。
这是我的示例的修改版本,可以根据上面的
CLibFunc
使用。这是假设 C 函数执行回调的方式是准确的。此外,这可能会稍微精简一些,具体取决于回调类的参与程度以及您需要的扩展自由度。
This just happens to be similar to something I'm in the middle of working on right now.
Here is an blog post on providing native callbacks using C++ classes: http://blogs.microsoft.co.il/blogs/alon/archive/2007/05/29/Native-Callback.aspx
I'm not familiar with calling C++ member functions from C, but I have done an interface (abstract base) class to another C++ class for callbacks (similar to the article). Here is a basic example of what I am providing a bridge for:
Now in order to make this available for managed implementations of the provider, we have to create a series of classes that provide the bridge.
Edit: Added code to show w/o the managed interface class example I use.
Here is a modified version of my example that can be used given your
CLibFunc
above. This is assuming how the C function performs the callback is accurate.Also this might be able to be slimmed down a bit depending on how involved your callback classes are and how much freedom for extension you need.