首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# 通過 P/Invoke 與 C++ DLL 中的 Event 實現線程同步

     編輯:程式設計綜合問答

核心思路

C++ 導出「註冊回調」函數,C# 傳遞委托作為函數指針,C++ 觸發事件時調用委托,C# 收到通知後 `EventWaitHandle.Set()` 喚醒等待線程。

C++ DLL 導出


// Callback 類型
typedef void (__stdcall *DataReadyCallback)(void* userData);

// 註冊
extern "C" __declspec(dllexport) void RegisterCallback(DataReadyCallback cb, void* userData) {
    g_callback = cb;
    g_userData = userData;
}

// 內部觸發
void OnDataReady() {
    if (g_callback) g_callback(g_userData);
}

C# 簽名與使用


[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate void DataReadyCallback(IntPtr userData);

[DllImport("CppDll.dll", CallingConvention = CallingConvention.StdCall)]
static extern void RegisterCallback(DataReadyCallback cb, IntPtr userData);

static EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.AutoReset);

static void Main() {
    DataReadyCallback cb = (userData) => wh.Set();
    GCHandle handle = GCHandle.Alloc(cb); // 防止委托被 GC
    RegisterCallback(cb, GCHandle.ToIntPtr(handle));
    
    // 等待信號
    wh.WaitOne();
    Console.WriteLine("C++ 事件觸發!");
    handle.Free();
}

注意

  • 委托必須 `GCHandle.Alloc` 防止被垃圾回收。
  • 調用約定 `StdCall` 雙方一致。
  • C++ 回調執行上下文可能是非托管線程,C# 委托內只做最小操作 (如 `Set()`)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved