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

C++ DLL 回調函數機制:底層事件通知上層應用的標準實作

     編輯:程式設計綜合問答

核心模式

DLL 導出「註冊回調」函數,應用層傳入函數指標/委派/lambda,DLL 內部事件發生時呼叫該回調。

C/C++ 介面定義


// DLL 端
typedef void (__stdcall *EventCallback)(int eventId, const char* data, void* userData);

__declspec(dllexport) void RegisterCallback(EventCallback cb, void* userData);
__declspec(dllexport) void UnregisterCallback();

// DLL 內部事件觸發
void OnDevicePhotoReady(const char* path) {
    if (g_callback) g_callback(EVENT_PHOTO_READY, path, g_userData);
}

應用層使用 (C++)


void __stdcall MyHandler(int id, const char* data, void* ctx) {
    if (id == EVENT_PHOTO_READY) {
        std::cout << "Photo: " << data << std::endl;
        // 更新 UI、存檔等
    }
}
int main() {
    RegisterCallback(MyHandler, nullptr);
    // ... 執行觸發拍照的操作 ...
    UnregisterCallback();
    return 0;
}

C# 呼叫 (P/Invoke)


[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate void EventCallback(int eventId, string data, IntPtr userData);

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

static EventCallback _handler = (id, data, ctx) => { /* ... */ };
RegisterCallback(_handler, IntPtr.Zero);
// 注意:_handler 必須保持存活防止 GC 回收,通常設為 static 欄位

進階:事件參數結構體


struct EventData {
    int eventId;
    int64_t timestamp;
    char payload[256];
};
typedef void (__stdcall *EventCallbackEx)(const EventData* evt, void* userData);

注意事項

  • 呼叫慣例統一(__stdcall / CallingConvention.StdCall)。
  • 跨模組記憶體:回調中傳遞的指標有效期需由 DLL 保證,或複製資料。
  • 執行緒安全:若 DLL 多執行緒觸發回調,應用層需自行同步(UI 執行緒 marshal)。
  • 生命週期:DLL 卸載前必須 UnregisterCallback,避免野指標呼叫。

原答案核心

「設備生成後直接調用回調函數」

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved