进程外COM组件的一个实例
生活随笔
收集整理的這篇文章主要介紹了
进程外COM组件的一个实例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
之前寫過一篇使用COM組件的3種方法的文章:啟動COM組件的三種機制,其中后來補充了一個用免注冊的方式使用進程外COM組件的方法,因為只是文字補充,沒有實例,可能對于怎么實現大家不是很清楚,陸續收到一些同學的信,希望能給個例子。 所以干脆補充一篇,自己也恰好復習一下。
步驟大概是這樣的:
我有一個com.exe的進程外com組件,暴露出一個ITestObject的接口。現在CustomizedWay.exe要調用這個com組件,但不希望通過注冊表那一套。 雖然微軟提供了registry-free的com組件機制,但目前只支持進程內COM組件(具體參考前文),但由于我們知道一個COM組件被調用的來龍去脈,我們可以跳過MS那一套,自己來完成這個工作 (如果你愿意,寫一個專門針對registry-free COM的庫也不是問題)。這個過程的代碼為:
HRESULT CreateMyRemoteHost(ITestObject** ppResult){
// Get the COM Server's full path (assume they are in the same folder)
wchar_t file[MAX_PATH] = {0};
if (!GetModuleFileName(NULL, file, MAX_PATH))
return E_FAIL;
wchar_t drive[_MAX_DRIVE] = {0};
wchar_t dir[_MAX_DIR] = {0};
_wsplitpath_s(file, drive, _MAX_DRIVE, dir, _MAX_DIR, NULL, 0, NULL, 0);
_wmakepath_s(file, MAX_PATH, drive, dir, L"Com", L"exe");
// Start process (It will insert its class factory object into a global table held by OS)
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
si.lpReserved = NULL;
si.lpTitle = NULL;
si.lpDesktop = NULL;
si.dwX = si.dwY = si.dwYSize = si.dwXSize = 0;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.lpReserved2 = NULL;
si.cbReserved2 = 0;
BOOL ret = CreateProcess(file, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
if (!ret) return E_FAIL;
WaitForInputIdle(pi.hProcess, 30000);
// Get class factory (from class table)
CComPtr<IClassFactory> pFactory;
HRESULT hr = CoGetClassObject(CLSID_TestObject, CLSCTX_LOCAL_SERVER, NULL, __uuidof(pFactory), reinterpret_cast<void**>(&pFactory));
if (FAILED(hr)) return hr;
// Query interface by class factory
return pFactory->CreateInstance(NULL, __uuidof(*ppResult), reinterpret_cast<void**>(ppResult));
}
這個過程中有幾點需要注意:
- manifest的創建
我們需要創建一個manifest來包含接口與tlb的信息,因為兩個進程間交互的時候,COM指針是需要marshalling的,而這個是通過tlb完成的。創建tlb的命令為:
manifest的集成
然后我們需要將這個manifest文件嵌入到com.exe和CustomizedWay.exe中,原因是進程間通信雙方都需要知道如何marshalling。如果直接使用一下命令:
mt.exe -manifest com.exe.manifest -outputresource:com.exe
mt.exe -manifest com.exe.manifest -outputresource:CustomizedWay.exe 在啟動程序時,會提示找不到:ATL##.dll和MSVCR##.dll,原因在于此處會把默認的manifest內容覆蓋掉,而那些內容,則包含了MFC,CRt的一些DLL的信息。所以我們需要先merge這兩個manifest,在嵌入到exe中去(mt.exe -manifest ...),但另外一個簡單的方法,就是把com.exe.manifest直接加入到兩個工程中,這樣在build的時候,就會將該manifest的內容添加進去 - 你可以用VS打開exe文件,查看里面的 RT_MANIFEST項。
具體可以下載sample:RegistryFree_COMExe
參考:
- 啟動COM組件的三種機制
- Mt.exe
- Assembly Manifest
總結
以上是生活随笔為你收集整理的进程外COM组件的一个实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .在OnPaint()函数和在OnEra
- 下一篇: 敏捷个人第六次练习讨论:个人价值观练习