標準 COM 透過 CoCreateInstance 建立物件,需註冊表、CLSID、IClassFactory 機制。純 C 專案或不想依賴 COM 執行期時,需更簡潔的載入方式。
參考 DirectX Direct3DCreate9 模式,在 COM DLL 內部實作並導出:
// COM 內部實作
HRESULT WINAPI GdiexCreate(LPVOID* lplpGdiex) {
ISaveDDCtrl* pCtrl = nullptr;
HRESULT hr = CoCreateInstance(CLSID_SaveDDCtl, NULL, CLSCTX_SERVER,
IID_ISaveDDCtl, (void**)&pCtrl);
if (FAILED(hr)) {
MessageBox(NULL, L"GdiexCreate Failed!", L"gdiexPS", MB_OK|MB_ICONSTOP);
return hr;
}
*lplpGdiex = pCtrl; // 直接回傳介面指標
return S_OK;
}
// 釋放對應函數
HRESULT WINAPI GdiexFree(LPVOID pCtrl) {
if (pCtrl) static_cast(pCtrl)->Release();
return S_OK;
}
; Gdiex.def
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
GdiexCreate
GdiexFree
#include "gdiex.h" // 宣告 GdiexCreate/GdiexFree
#pragma comment(lib, "gdiex.lib")
ISaveDDCtl* pCtl = nullptr;
CoInitialize(NULL);
HRESULT hr = GdiexCreate((LPVOID*)&pCtl);
if (SUCCEEDED(hr)) {
// 使用 pCtl...
GdiexFree(pCtl);
}
CoUninitialize();
| 優點 | 缺點 |
|---|---|
| 無需註冊表/CLSID,部署簡單 (XCopy deploy) | 失去 COM 定位/版本管理/進程外激活能力 |
| C/C++ 直接調用,無互操作開銷 | 需手動管理 DLL 載入/卸載 (LoadLibrary/FreeLibrary) |
| 介面指標直接回傳,型別安全 | 單一 DLL 只能導出一組工廠,擴充性弱 |
| 適合插件架構、輕量級元件 | 跨語言 (C#/VB) 需 P/Invoke,不如標準 COM 友善 |
LoadLibrary → GetProcAddress("PluginCreate") → 取得介面。