COM 的二進制相容性承諾使得不同語言開發的元件能無縫互操作。本文實戰記錄如何在 VC 6.0 專案中呼叫 Delphi 5.0 開發的進程內 COM 伺服器,核心在於 IDL 檔案的轉換與介面定義的正確對應。
Delphi 產生的 .idl 檔案需經 MIDL 編譯器產生 VC 可用的 .h 與 _i.c 檔案。作者分享了繞過 MIDL 直接操作的實用技巧:
ttt)ttt.idl、ttt.h、ttt_i.cmadll.idl 覆寫 ttt.idlmadll.h、madll_i.cDelphi 5.0 建立進程內 COM 伺服器步驟:
ImaCom 並加入方法 ShowMamadll.dll 與 madll.idlregsvr32 madll.dll
// 專案設定:加入 madll.h 路徑至 Additional Include Directories
#include "madll.h" // 包含介面定義與 CLSID/IID
void CMacppDlg::OnButton1()
{
HRESULT hr;
ImaCom* pmaCom = NULL;
// 1. 初始化 COM 程式庫
hr = CoInitialize(NULL);
if (FAILED(hr)) return;
// 2. 建立 COM 物件實例
hr = CoCreateInstance(
CLSID_maCom, // 從 madll_i.c 取得
NULL,
CLSCTX_INPROC_SERVER, // 進程內伺服器
IID_ImaCom, // 從 madll_i.c 取得
(void**)&pmaCom
);
if (SUCCEEDED(hr) && pmaCom)
{
// 3. 呼叫 COM 方法
// 參數:介面指標、視窗控制代碼(用於訊息框父視窗)
pmaCom->ShowMa(NULL, (WORD)GetSafeHwnd());
// 4. 釋放介面指標
pmaCom->Release();
}
// 5. 反初始化 COM
CoUninitialize();
}
| 檔案 | 來源 | 用途 |
|---|---|---|
| madll.dll | Delphi 編譯 | COM 伺服器執行體,需註冊 |
| madll.idl | Delphi 產生 | 介面定義語言原始碼 |
| madll.h | MIDL 編譯 madll.idl | C++ 介面宣告、虛函數表定義 |
| madll_i.c | MIDL 編譯 madll.idl | CLSID/IID/GUID 實際數值定義 |
// 註冊(管理員權限) regsvr32 madll.dll // 反註冊 regsvr32 /u madll.dll // 若 DLL 不在系統路徑,需指定完整路徑 regsvr32 "C:\MyProject\madll.dll"常見問題排查
madll_i.c 加入專案編譯作者附帶原始碼包含兩個專案:
DelphiCallVCCOM.zip:Delphi 呼叫 VC COMVCCallDelphiCOM.zip:VC 呼叫 Delphi COM(本文主角)雙向驗證證明 COM 的語言中立特性,關鍵在於標準化的 IDL 定義與二進制介面契約。
VC 呼叫 Delphi COM 的核心流程:Delphi 產出 IDL → MIDL 編譯產生 C++ 標頭/識別碼檔 → VC 專案引入並以標準 COM API 呼叫。掌握 IDL 到 C++ 定義的轉換機制,即可打通任意語言邊界的元件復用通道。