從 32bit 應用呼叫 64bit DLL 的方法 - COM 橋接有用的案例研究
· 小村 豪 · COM, Windows 開發, 32bit, 64bit
從 32bit 應用呼叫 64bit DLL 的方法 - COM 橋接有用的案例研究
「想從 32bit 應用呼叫 64bit DLL」這個需求,在 Windows 上相當典型。 尤其是在保留既有資產的同時,只想使用 64bit 側的功能時,COM 橋接的架構往往是相當實際的解法。
1. 假設情境
在維持 32bit 既有應用的前提下,想使用 64bit DLL 的處理 的情境。
但 32bit 行程無法載入 64bit DLL,這是 OS 層級的限制。
常見的情況如下。
- 既有 32bit 應用作為資產已經很龐大,無法立即遷移
- 64bit DLL 一側有新功能,或相依函式庫只有 64bit 版本
- 想從 32bit 側「以型別」方式呼叫
此時,「在同一行程內呼叫」是不可能的。
2. 解決方式
解決的基本思路是 用 Out-of-proc COM(EXE 伺服器)切開。
64bit DLL 由 64bit 的 COM 伺服器(EXE)來呼叫,32bit 應用則透過 COM 使用。
流程如下。
- 準備 64bit 的 COM LocalServer(EXE),在其內部呼叫 64bit DLL
- 共享 COM 介面(IDL/TypeLib),公開型別
- 32bit 應用以「帶型別」的方式透過 COM 呼叫(由 Proxy/Marshal 交換)
需要注意的地方如下。
- 32bit/64bit 的註冊是分開的(包含 WOW6432Node)
- 自訂結構需要設計 marshalling
- 存在 IPC 的額外成本,高頻率呼叫要留意
換句話說,「把 64bit 的處理放到另一個行程,再用 COM 搭橋」 是王道做法。
3. 處理流程(序列圖)
以下是 32bit 應用呼叫 64bit DLL 處理時的流程。
sequenceDiagram
participant App as 32bit 客戶端應用
box rgba(100,100,255,0.1) COM 自動處理(開發者不用特別注意)
participant Proxy as COM Proxy
(32bit 側)
participant RPC as RPC/IPC
(跨行程通訊)
participant Stub as COM Stub
(64bit 側)
end
participant Server as 64bit COM Server
(EXE)
participant DLL as 64bit DLL
App->>Proxy: ICalcService.Add(1, 2)
rect rgba(100,100,255,0.1)
Note over Proxy: 將參數做 marshalling
Proxy->>RPC: 序列化後的資料
RPC->>Stub: 跨越行程邊界傳輸
Note over Stub: 將參數做 unmarshalling
end
Stub->>Server: Add(1, 2)
Server->>DLL: 原生函式呼叫
DLL-->>Server: 結果: 3
Server-->>Stub: 結果: 3
rect rgba(100,100,255,0.1)
Note over Stub: 將回傳值做 marshalling
Stub-->>RPC: 序列化後的結果
RPC-->>Proxy: 跨越行程邊界傳輸
Note over Proxy: 將回傳值做 unmarshalling
end
Proxy-->>App: 結果: 3
重點:
- 32bit 應用可以透過
ICalcService介面做型別安全的呼叫 - COM runtime 會自動生成並管理 Proxy/Stub
- 存在跨行程通訊的額外成本,因此與其頻繁的細碎呼叫,不如偏向批次處理
4. 範例程式(示意)
以下是 概念示意。實務上還需要註冊與 TypeLib 生成等步驟。
// 共享介面(對應 IDL)
[ComVisible(true)]
[Guid("7A4B5B23-0A2F-4D2B-9D4D-8A2A92B8B001")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICalcService
{
int Add(int a, int b);
}
// 64bit COM LocalServer(EXE 側)
[ComVisible(true)]
[Guid("1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11")]
[ClassInterface(ClassInterfaceType.None)]
public class CalcService : ICalcService
{
public int Add(int a, int b)
{
// 在此呼叫 64bit DLL
return a + b;
}
}
// 32bit 應用側(Client)
Type t = Type.GetTypeFromProgID("KomuraSoft.CalcService");
var calc = (ICalcService)Activator.CreateInstance(t);
int result = calc.Add(1, 2);
做成這個樣子之後,32bit 側就能以 「帶型別」 的方式使用。
COM 會在內部透過 Proxy/Stub 經由 IPC 呼叫。
5. 完整範例程式
將上述概念做成可實際執行的範例,公開在 GitHub。
Call64bitDLLFrom32bitProc - GitHub
此儲存庫包含:
- Call64bitDLLFrom32bitProc/ - 64bit COM LocalServer (EXE)
- X64DLL/ - 64bit DLL(實際處理)
- X86App/ - 32bit 客戶端 (WinForms)
- scripts/ - COM 伺服器註冊/解除註冊腳本
依照 README 的步驟建置與註冊後,就能實際確認從 32bit 行程呼叫 64bit DLL 的運作。
6. 參考資料
- Component Object Model (COM) 概觀
https://learn.microsoft.com/en-us/windows/win32/com/component-object-model–com–portal - COM LocalServer32 的註冊
https://learn.microsoft.com/en-us/windows/win32/com/localserver32 - COM 介面的基礎
https://learn.microsoft.com/en-us/windows/win32/com/the-component-object-model - COM Interop(從 .NET 使用)
https://learn.microsoft.com/en-us/dotnet/standard/native-interop/cominterop
相關文章
共用相同標籤的最新文章。能以相近的主題延伸理解。
開發 COM 元件、OCX/ActiveX 時常見的坑 - 整理 Visual Studio 的 32bit/64bit、註冊、管理員權限
整理開發 COM、OCX、ActiveX 元件時最容易卡關的四個面向:宿主行程的 32bit/64bit、Visual Studio 2022 變成 64bit 後的設計時整合、regsvr32 與 Regasm 的註冊位置、以及管理員權限與 HKCU/HKLM 的關係,協...
什麼是 Reg-Free COM - 免註冊使用 COM 的機制,以及合用與不合用的情境
整理 Reg-Free COM 的本質、執行時 activation context 與 manifest 的協作方式,以及好處與極限。同時釐清 bitness、相依 DLL、TLB/設計時參考是另一條線,幫助你判斷哪些情境適合導入、哪些情境得另想辦法,並避開常見的部署陷阱。
Excel 報表輸出該怎麼做 - COM 自動化 / Open XML / 範本方式的判斷表
從 Windows 應用與業務系統的角度,把 Excel 報表輸出拆成驅動 Excel 與組裝 Excel 檔案兩條路。整理 COM 自動化、Open XML 直接生成、範本套版、既有 VBA 併用的取捨,並針對使用者編輯、夜間批次、大量輸出等情境,給出不易壞且容易維運的選...
COM / ActiveX / OCX 是什麼 - 差異與關係一次整理
從實務角度釐清 COM、ActiveX、OCX 三者的差異與關係:COM 是 Windows 元件互動的 binary 契約底層,ActiveX 是以 COM 為基礎的可嵌入 control 脈絡,OCX 則為 ActiveX control 常見的副檔名。讀完能分清機制、...
ActiveX / OCX 現在如何處理 - 保留・包裝・取代的判斷表
整理在實務專案中遇到 ActiveX 或 OCX 時的判斷流程,從 UI 部件、機器控制、報表、瀏覽器依賴到 32bit 與 64bit 的牆壁,依照保留・包裝・取代三種選項列出對照表與決策流程,並說明註冊發佈與 STA 等容易絆倒的細節,幫讀者選出最低成本的下一步。
相關主題
與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。
Windows 技術主題
彙整 KomuraSoft LLC 關於 Windows 開發、故障調查與既有資產活用文章的主題中心。
ActiveX 遷移
整理保留、包裝或替換 COM / ActiveX / OCX 資產的階段性判斷的主題頁面。
32 位元 / 64 位元互通
整理 32 位元 / 64 位元互通、原生邊界與相關 Windows 設計判斷的主題頁面。
與本主題相關的服務
本文連結到以下服務頁面,歡迎從最接近的入口查看。
Windows 應用程式開發
支援包含常駐處理、設備連動、運作日誌與可維護結構的 Windows 桌面應用程式。
既有資產活用 & 遷移支援
在持續活用 COM / ActiveX / OCX 資產、原生程式碼與 32 位元相依的同時,協助規劃階段性的遷移。
作者檔案
本文作者的個人檔案頁面。
Go Komura
小村軟體有限公司 代表
以 Windows 軟體開發、技術諮詢與故障調查為中心,在難以重現的故障調查與既有資產仍在運作的專案上具有優勢。