1. 程式人生 > >COM程序外元件的實現vc++

COM程序外元件的實現vc++

說明程序外元件的實現有三個部分組成分別是:

程序外元件:com_test->simple(介面)

代理存根  :com_proxy

客戶端    :com_client

開發環境:WIN7+VS2010

(一) 建立程序外元件

使用VS2010建立ATL專案,專案名稱是com_test,點選確定之後需要注意的是選擇可執行程式,而不是dll!,其他保持預設,之後類似程序內元件,新增一個簡單物件,

simple,同時新增一個自定義介面,我是這樣做的,分別修改三個檔案 com_test.idl,simple.c和simple.cpp

在com_test.idl檔案的介面描述中新增

interface Isimple : IDispatch{
	HRESULT test(int a,int b);
};

在simple.h檔案中新增

STDMETHOD(test)(int a,int b);

在simple.cpp檔案中新增

STDMETHODIMP Csimple::test (int a,int b)
{
	int c=a+b;
	char buf[20]={0};
	sprintf(buf,"%d",c);
	MessageBoxA(NULL,buf,"test",0);
	return S_OK;
}

之後Ctrl+F5即可完成,這樣程序外元件就完成了

(二)代理存根物件的實現com_proxy.dll

將com_test.idl檔案儲存到一個比較乾淨的目錄當中,使用VS2010的midl工具,進入com_test.idl檔案所在目錄,使用midl ..\com_test.idl命令來編譯獲

得com_test.h,com_test.tlb,com_test_i.c,com_test_p.c,dlldata.c,然後建立win32的控制檯專案,注意建立一個dll的空專案,新增上述6個檔案,編輯專案屬性,其實修

改的只有兩處,一是:C++的前處理器中的預處理定義新增  REGISTER_PROXY_DLL,二是在連結器條目的輸入項中新增依賴項 rpcrt4.lib和uuid.lib,然後Crel+F5即可得到

com_test即可。

(三)模擬客戶端com_client

建立一個win32的控制檯專案,原始碼如下:

#include
#include
#include"interface.h"//裡面的內容是com_proxy專案中生成的.h檔案
using namespace std;
extern "C" const GUID IID_Isimple=
{
	0xEFEFD281,0xBF44,0x416B,{0xBF,0x21,0x82,0xBA,0x42,0xF5,0x8A,0x4D}//在interface標頭檔案中尋找
};
extern "C" const GUID CLSID_simple=
{
	0xB9FB4559,0x22AB,0x4D9E,{0xA0,0xE1,0xE2,0x89,0x3C,0x54,0x40,0x25}

};
int _tmain(int argc, _TCHAR* argv[])
{
	::CoInitialize (NULL);
	IUnknown*pUnk=NULL;
	Isimple* psim=NULL;
	HRESULT hr=::CoCreateInstance(CLSID_simple,NULL,CLSCTX_LOCAL_SERVER,IID_Isimple,(void**)&pUnk);
	if(S_OK==hr)
	{
		cout<<"CoCreateInstance successfully\n";		
	}
	else
		return 0;
	hr=pUnk->QueryInterface(IID_Isimple,(void**)&psim);
	if(S_OK==hr)
	{
		cout<<"QueryInterface successfully\n";
	}
	else
		return 0;
	hr=psim->test (2,3);
	psim->Release();
	pUnk->Release();
	return 0;
}

這樣程序外元件就實現了但是還有一個問題,就是如果成員方法引數中含有指標則會失敗,比如

 
HRESULT test(BSTR var)
{
MessageBox(NULL,var,L"測試",0);
return S_OK;
}

測試時不會得到任何內容,除此之外,我們怎麼保證在客戶端退出時,程序外元件也會同樣退出???that is a problem,but not this blog to solve,so i will continue.