首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 實作 DLL 與 EXE 間自訂訊息傳遞:完整步驟與程式碼範例

     編輯:VC 教學

前言:DLL 與 EXE 通訊的最佳方式

底層硬體開發、即時資料接收等場景中,DLL 需主動通知 EXE 處理結果。自訂訊息是最標準、解耦的方式。本文詳細說明 EXE 內部自訂訊息與 DLL→EXE 跨模組訊息傳遞的完整實作步驟。

一、EXE 內部自訂訊息實作

1. 定義訊息值

在 stdafx.h 或 View/Dialog 標頭檔:

#define WM_MYMSG (WM_USER + 101)  // 保留 WM_USER~WM_USER+100 給系統控件

2. 宣告訊息處理函數 (AFX_MSG 區塊)

// CMyView.h / CTestMessageDLLDlg.h
protected:
    // {{AFX_MSG(CMyView)
    afx_msg LRESULT OnMyMsg(WPARAM wParam, LPARAM lParam);
    // }}AFX_MSG
    DECLARE_MESSAGE_MAP()

3. 訊息映射 (MESSAGE_MAP)

BEGIN_MESSAGE_MAP(CMyView, CView)
    // {{AFX_MSG_MAP(CMyView)
    ON_MESSAGE(WM_MYMSG, OnMyMsg)
    // }}AFX_MSG_MAP
END_MESSAGE_MAP()

4. 實作處理函數

LRESULT CMyView::OnMyMsg(WPARAM wParam, LPARAM lParam)
{
    AfxMessageBox(_T("收到自訂訊息!"));
    return 0;
}

5. 發送訊息

::PostMessage(hWnd, WM_MYMSG, 0, 1);  // 非同步,不等待
// 或
::SendMessage(hWnd, WM_MYMSG, 0, 1);  // 同步,等待處理完成

二、DLL → EXE 跨模組訊息傳遞

關鍵差異:DLL 與 EXE 必須定義相同訊息值,且 EXE 需將接收視窗句柄 HWND 傳給 DLL。

DLL 端實作

// stdafx.h (DLL 專案)
#define WM_MYMSG (WM_USER + 102)  // 與 EXE 完全一致

// MessageDLL.h
class CMessageDLLApp : public CWinApp
{
public:
    void SendMessage(HWND hWnd);  // 匯出函數實作
};

// MessageDLL.cpp
CMessageDLLApp theApp;

extern "C" __declspec(dllexport) void StartSendMessage(HWND hWnd)
{
    theApp.SendMessage(hWnd);
}

void CMessageDLLApp::SendMessage(HWND hWnd)
{
    ::PostMessage(hWnd, WM_MYMSG, 0, 1);
}

EXE 端實作

// stdafx.h (EXE 專案) - 訊息值必須相同
#define WM_MYMSG (WM_USER + 102)

// CTestMessageDLLDlg.h - 同樣宣告 OnMyMsg、ON_MESSAGE 映射

// 對話框按鈕點擊:動態載入 DLL 並呼叫
void CTestMessageDLLDlg::OnBnClickedButton1()
{
    typedef void (_cdecl* STARTSENDMESSAGE)(HWND);
    HMODULE hDll = LoadLibrary(_T("MessageDLL.dll"));
    if (!hDll) { AfxMessageBox(_T("載入 DLL 失敗")); return; }

    STARTSENDMESSAGE pfn = (STARTSENDMESSAGE)GetProcAddress(hDll, "StartSendMessage");
    if (!pfn) { FreeLibrary(hDll); AfxMessageBox(_T("取得函數位址失敗")); return; }

    HWND hWnd = GetSafeHwnd();
    pfn(hWnd);  // 呼叫 DLL 匯出函數,DLL 內部 PostMessage 給此視窗

    FreeLibrary(hDll);
}

關鍵點總結

項目說明
訊息值定義DLL/EXE 完全一致,建議用共用標頭檔避免不一致
HWND 傳遞EXE 必須將接收視窗句柄傳給 DLL(透過匯出函數參數)
呼叫約定匯出函數建議用 __cdecl 或 __stdcall 明確指定
PostMessage vs SendMessagePostMessage 非阻塞;SendMessage 同步阻塞,跨模組慎用避免死結
錯誤處理LoadLibrary/GetProcAddress 必須檢查回傳值

進階延伸

  • 使用 RegisterWindowMessage 取得系統唯一訊息 ID,避免衝突。
  • DLL 端若為多執行緒,發送訊息前確認 IsWindow(hWnd)。
  • 大量資料傳遞可用 WM_COPYDATA 或共享記憶體配合訊息通知。

結語

自訂訊息是 DLL/EXE 解耦通訊的基石。掌握「定義相同訊息值、傳遞 HWND、動態載入 DLL 呼叫匯出函數」三步驟,即可靈活實現模組間非同步通知。

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