在 C# 中调用包含回调的 C++ 函数

Gel*_*ion 6 c# c++ api callback dllimport

大家好,我正在尝试在 C# 中调用这个 C++ 函数:

BOOL __stdcall CodecStart(int hRadio,void __stdcall (*CallbackFunc)(void *),void *CallbackTarget);
Run Code Online (Sandbox Code Playgroud)

这是来自此处http://www.winradio.com/home/g305_sdk.htm的 WinRadio api 。

我确实发现其他人要求在网上调用这个特定的函数,他们有:

    public delegate void CallbackFunc( IntPtr p);

    [DllImport("WRG305API.dll")]
    public static extern bool CodecStart(int hRadio, CallbackFunc func, IntPtr CallbackTarget);
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚如何进一步实施。

关于如何称呼它的任何想法或指导?

非常感谢

AVI*_*per 5

这是一个简单的实现,可以将它们放在一起。

class WinRadioWrapper
{
    public delegate void CallbackFunc( IntPtr pData );

    [DllImport( "WRG305API.dll" )]
    public static extern bool CodecStart( int hRadio, CallbackFunc func, IntPtr CallbackTarget );

    public bool CodecStartTest(int hRadio)
    {
        bool bStarted = CodecStart( hRadio, MyCallbackFunc, IntPtr.Zero );
        return bStarted;
    }

    // Note: this method will be called from a different thread!
    static void MyCallbackFunc( IntPtr pData )
    {
        // Sophisticated work goes here...
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 请注意,因为MyCallbackFunc将在不同的线程上执行,所以我选择 make is static。这样您就不会被诱惑访问WinRadioWrapper数据成员。

  • 为简单起见,我IntPtr.Zero向回调传递了一个参数,但这可以指向您想在回调中使用的任何数据。

    [请忽略此段]看看Marshal.StructureToPtr您是否想将数据传递给回调,但请确保同时固定您正在传递的数据,以确保它不会被垃圾收集(GCHandle有关更多详细信息,请参见)。

编辑:
通过svick的有趣的话(谢谢!),我意识到我正在将复制的对象与固定的对象混合在一起。
所以,整理一下:

  • Marshal.StructureToPtr 如果您想复制现有数据结构,然后将其传递给回调函数,则应该使用它。
  • 如果,另一方面,你想使用和现有的数据结构(例如修改其内容)时,你应该使用GCHandle它在内存中,并防止它被当作垃圾回收。
    但是,这将为GCHandle.