none
C#调用非托管DLL的导出函数,回调函数的调用怎么进行 RRS feed

  • 问题

  • 我用C#调用非托管DLL中的导出函数。普通的导出函数一切正常,在C语言一端的const char*,能够正常变为C#一端的string

    然而,回调函数有些问题,我在C#端没有抛出异常,但是参数传递的字符串是空的。

    我的回调函数定义如下(C++):

    // 函数指针定义
    typedef void(*EVENT_CALLBACK)(const char* message);
    
    // ...
    // 一个声明
    EVENT_CALLBACK _eventCallback = 0;
    
    // ...
    // 导出函数定义
    MY_API void RegisterEventHandler(EVENT_CALLBACK callback) {
        _eventCallback = callback;
    }
    
    // ...
    // 调用已注册的回调函数,传出一个字符串
    _eventCallback("某一个消息");

    在C#一方的方式如下:

    // ...
    // 委托的定义。返回void,参数是一个string
    public delegate void EVENT_CALLBACK_DELEGATE(string message);
    
    // ...
    // 定义这个导出函数
    [DllImport("MyDLL")]
    public static extern void RegisterEventHandler(EVENT_CALLBACK_DELEGATE callback);
    
    
    // ...
    // 程序刚启动时,调用上面的导出函数注册一个回调
    EVENT_CALLBACK_DELEGATE callback = new EVENT_CALLBACK_DELEGATE(OnMyDLLEvent);
    RegisterEventHandler(callback);
    
    // ..
    // 被DLL调用的函数,传入的字符串总是空的
    static public void OnMyDLLEvent(string message)
     {
        // 这里的message总是空的
        Console.WriteLine(message);
     }

    不知道哪里有问题呢?


    • 已编辑 srhouyu 2017年7月28日 14:00 修改内容
    2017年7月28日 13:59

全部回复

  • Hi,

    感谢在MSDN论坛发帖。

    据我所知,非托管的代码之所以能在托管代码中运行,得益于元数据的作用。

    CLR会把非托管中的数据,函数都会暴露出来,对于数据使用marsh的。 你这个直接定义,都没有marsh,会不会导致这个错误。

    从MSDN的官网中,在非托管的代码中,定义的回调函数,是没有带参数的。

    typedef void (__stdcall *PFN_MYCALLBACK)();
    int __stdcall MyFunction(PFN_ MYCALLBACK callback);

    我建议你应该先marsh这个数据,然后传递给回调函数。

    Best Regards,

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年7月31日 9:30
    版主