首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将C回调函数封装在C#函数中

将C回调函数封装在C#函数中
EN

Stack Overflow用户
提问于 2015-03-02 09:17:21
回答 1查看 454关注 0票数 0

我需要使C#程序可以访问用C编写的DLL。我用C#编写了一个包装器DLL,它封装了每个C接口函数。我给出了一个功能良好的代码,但最终崩溃的消息如下:

托管调试助手“CallbackOnCollectedDelegate”检测到了CallbackOnCollectedDelegate中的一个问题 附加信息:对类型为'vJoyInterfaceWrap!vJoyInterfaceWrap.vJoy+WrapFfbCbFunc::Invoke'.的垃圾收集委托进行回调。

造成崩溃的部分与C#代码向DLL注册的回调函数相关。当DLL从注册的回调函数调用(或返回)时,就会发生崩溃。

C DLL接口:

代码语言:javascript
复制
// Definition of callback function prototype
// Parameter 1: Pointer to a data structure to be used inside the CB function
// Parameter 2: Pointer to user-defined data passed during registration
typedef void (CALLBACK *FfbGenCB)(PVOID, PVOID);

// Registration of CB function.
// Parameter cb is a pointer to the callback function.
// Parameter data is a pointer to user-defined data
VOID        __cdecl FfbRegisterGenCB(FfbGenCB cb, PVOID data);

C#接口:

我希望用户定义的数据是一个对象(而不是IntPtr)。为此,我使用一个预定义的回调函数封装用户的回调函数,该函数将IntPtr转换为对象。在注册过程中,我注册了预定义的回调函数,并将用户定义的数据( C#对象)转换为IntPtr。

代码语言:javascript
复制
// The user-defined CB function is of type FfbCbFunc
//  FfbCbFunc is defined:
public delegate void FfbCbFunc(IntPtr data,  object userData);

// The registration of the predefined callback function _WrapFfbCbFunc is done by calling
// function FfbRegisterGenCB:
       public void FfbRegisterGenCB(FfbCbFunc cb, object data)
        {
            // Convert object to pointer
            GCHandle handle1 = GCHandle.Alloc(data);

            // Apply the user-defined CB function
            _g_FfbCbFunc = new FfbCbFunc(cb);
            WrapFfbCbFunc wf = new WrapFfbCbFunc(_WrapFfbCbFunc);

            _FfbRegisterGenCB(wf, (IntPtr)handle1);
        }

以下是其他定义和声明:

代码语言:javascript
复制
// Placeholder for user defined callback function
private static FfbCbFunc _g_FfbCbFunc;

// predefined callback function that encapsulates the user-defined callback function
public delegate void WrapFfbCbFunc(IntPtr data, IntPtr userData);
public void _WrapFfbCbFunc(IntPtr data, IntPtr userData)
        {
            // Convert userData from pointer to object
            GCHandle handle2 = (GCHandle)userData;
            object obj = handle2.Target as object;

            // Call user-defined CB function
            _g_FfbCbFunc(data, obj);
        }
EN

回答 1

Stack Overflow用户

发布于 2015-03-03 09:39:34

包装器回调函数及其引用必须是静态

代码语言:javascript
复制
// Make wf global and static
private static WrapFfbCbFunc wf;

// Make the wrapping callback function static
public static void  _WrapFfbCbFunc(IntPtr data, IntPtr userData)
{

    object obj = null;

    if (userData != IntPtr.Zero)
    {
        // Convert userData from pointer to object
        GCHandle handle2 = (GCHandle)userData;
        obj = handle2.Target as object;
    }

    // Call user-defined CB function
    _g_FfbCbFunc(data, obj);
}

附注:

我不认为这是一个如此糟糕的问题,以1票的奖励。就我个人而言,我只是忽略了一些毫无意义的问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28806140

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档