本文詳細介紹了如何在 windows ce 6.0 系統(tǒng)上開發(fā) dcom 服務(wù)進程,以提供跨進程的 com 組件服務(wù),并創(chuàng)建和注冊自定義接口代理/存根 dll。
假設(shè)您需要開發(fā)一個實時控制程序,該程序需要在后臺持續(xù)運行,而客戶端可能多樣且使用不同的開發(fā)語言。這就需要創(chuàng)建一個 COM 服務(wù)進程程序。
在 Windows CE 鏡像中,必須包含 DCOM 組件服務(wù)。然而,由于系統(tǒng)空間限制,許多基于 Windows CE 的操作系統(tǒng)不支持 DCOM。您需要使用 Platform Builder 向 Windows CE 鏡像中添加 DCOM。此外,還必須導(dǎo)出支持 DCOM API 的 Windows CE SDK 開發(fā)包。
其他必備工具包括用于注冊 COM DLL 的 GuiRegsvrCE.exe,這類工具可以在網(wǎng)上找到。
創(chuàng)建 COM Server
由于 Windows CE 不支持自動化封送/解封送,我們需要為 COM Server 和 Client 之間的接口方法參數(shù)創(chuàng)建自己的代理/存根。在 Windows XP/2000 系統(tǒng)中,如果 COM 方法使用 OLE 兼容的數(shù)據(jù)類型,我們可以不提供代理/存根 DLL。但如果使用自定義數(shù)據(jù)類型,則需要創(chuàng)建并注冊相應(yīng)的代理/存根代碼。
在開發(fā) Windows CE COM Server 時,需要將 IDL 文件中的 LIBRARY 塊中的 dispinterface 定義移到 LIBRARY 塊外部。所有接口都必須在 LIBRARY 塊外部定義,這樣 MIDL 編譯器才能生成正確的代理/存根代碼。
注意,sink dispinterface 接口需要重新定義為 dual 并從 IDispatch 接口派生。
[object, uuid(8D2D2A49-E8D3-4630-924D-1F83A4B063DB), dual, nonextensible, helpstring("IAlgorithm 接口"), pointer_default(unique)] interface IAlgorithm : IDispatch { [id(1), helpstring("方法Add")] HRESULT Add([in] LONG n1, [in] LONG n2, [out,retval]LONG* nVal); [id(2), helpstring("方法Minus")] HRESULT Minus([in] LONG n1, [in] LONG n2, [out,retval] LONG* nVal); [id(3), helpstring("方法Input")] HRESULT Input([in] BSTR str); }; <h1>ifdef UNDER_CE</h1><p>[uuid(C33B6BCD-ABBB-4E80-8E55-F34CC867BE83), dual, helpstring("_IAlgorithmEvents 接口")] interface _IAlgorithmEvents : IDispatch { //properties: //methods: [id(1), helpstring("方法Output")] HRESULT Output([in] BSTR str); };</p><h1>endif //UNDER_CE</h1><p>[uuid(4EC8BE3C-DF5C-4E56-B1F5-9350266E32FC), version(1.0), helpstring("ServDemo 1.0 類型庫")] library ServDemoLib { importlib("stdole2.tlb"); interface IDocHostUIHandlerDispatch; interface IAxWinAmbientDispatchEx;</p><pre class="brush:php;toolbar:false">#ifndef UNDER_CE [uuid(C33B6BCD-ABBB-4E80-8E55-F34CC867BE83), helpstring("_IAlgorithmEvents 接口")] dispinterface _IAlgorithmEvents { properties: methods: }; #endif //UNDER_CE [uuid(9EEFFB69-1604-4DA2-A12A-FAB65CE9D587), helpstring("Algorithm Class")] coclass Algorithm { [default] interface IAlgorithm; [default, source] dispinterface _IAlgorithmEvents; };
};
代理存根 DLL 的創(chuàng)建
創(chuàng)建代理存根 DLL 與 PC 端類似,但需要定義一些宏才能編譯通過,并定義一個 def 文件,注明要導(dǎo)出的函數(shù)。
// dlldata.c 的包裝</p><h1>define REGISTER_PROXY_DLL //DllRegisterServer 等</h1><h1>ifndef _WIN32_WCE</h1><h1>define _WIN32_WINNT 0x0400//對于 WinNT 4.0 或安裝了 DCOM 的 Win95</h1><h1>else</h1><h1>define WIN32</h1><h1>endif</h1><h1>define USE_STUBLESS_PROXY//僅當使用 MIDL 開關(guān) /Oicf 時定義</h1><h1>ifndef _WIN32_WCE</h1><h1>pragma comment(lib, "rpcns4.lib")</h1><h1>endif</h1><h1>pragma comment(lib, "rpcrt4.lib")</h1><p>//#define ENTRY_PREFIXPrx</p><h1>include "dlldata.c"</h1><h1>include "ServDemo_p.c"
編譯完成后,進程外 COM Server 的開發(fā)基本完成,但需要在機器上注冊才能使用。
如何調(diào)用進程外組件(Client 程序)
對于客戶端,調(diào)用進程外組件與調(diào)用進程內(nèi)組件基本相同。我提供了一些輔助代碼《EventHandler.h》,幫助客戶端在不使用 ATL 的情況下接收 COM Server 的事件。
源代碼下載:https://www.php.cn/link/85d52e4d4b40d62fa159037686630a7c