Windows本身支持成为一个RPC服务器。MSDN里面有个很好的例子,但是,WindowsXP上面默认的RPC/tcpip功能没有打开,必须运行gpedit.msc,计算机配置->管理模版->系统->远程过程调用->用于未验证的RPC...->选择"已启动",限定项选择"无"。用VC2010express建立两个工程,按照MSDN的例子:
首先,idl文件my.idl:
[
uuid(ba209999-0c6c-11d2-97cf-00c04f8eea45),
version(1.0)
]
interface hw // The interface is named hw
{
// A function that takes a zero-terminated string.
void Hello(
[in, string] const char* szOutput);
}
|
编译以后,相应的文件放到服务器端和客户端程序里面去。
服务器端实现:
#include"stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include"my_h.h"
#pragma comment(lib,"rpcrt4")
#pragma comment(lib,"ole32")
extern "C"{
void Hello(handle_t IDL_handle,const unsigned char*psz){
printf("server:%s\n",psz);
}
void Shutdown(handle_t IDL_handle){
RpcMgmtStopServerListening(NULL);
RpcServerUnregisterIf(NULL,NULL,FALSE);
}
void* /*__RPC_FAR**/ __RPC_USER midl_user_allocate(size_t len){
return(malloc(len));
}
void __RPC_USER midl_user_free(void __RPC_FAR* ptr){
free(ptr);
}
}
int main()
{
RPC_STATUS status;
status = RpcServerUseProtseqEp(
(RPC_CSTR)("ncacn_ip_tcp"), // Use TCP/IP protocol.
RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // Backlog queue length for TCP/IP.
(RPC_CSTR)("4747"), // TCP/IP port to use.
NULL); // No security.
if (status){
printf("ServerUse failed\n");
exit(status);}
else printf("UseProtseqEq ok\n");
status = RpcServerRegisterIf(
hw_v1_0_s_ifspec, // Interface to register.
NULL, // Use the MIDL generated entry-point vector.
NULL);// Use the MIDL generated entry-point vector.
if (status){
printf("Register failed\n");
exit(status);}
else printf("Register if ok\n");
// This call will not return until
// RpcMgmtStopServerListening is called.
status = RpcServerListen(
1, // Recommended minimum number of threads.
RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Recommended maximum number of threads.
FALSE); // Start listening now.
if (status){
printf("Server listen failed\n");
exit(status);}
else printf("listen ok\n");
return 0;
}
|
启动以后显示:
UseProtseqEq ok
Register if ok
客户端代码:
// myclient.cpp : Defines the entry point for the console application.
#include"stdafx.h"
#include<windows.h>
#include<stdio.h>
#include"my_h.h"
#pragma comment(lib,"rpcrt4")
#pragma comment(lib,"ole32")
int main(void){
RPC_STATUS status;
RPC_BINDING_HANDLE hwBinding;
unsigned char* szStringBinding=NULL;
status=RpcStringBindingCompose(//建立一个String Binding句柄,并不连接
NULL,
(RPC_CSTR)("ncacn_ip_tcp"),
(RPC_CSTR)("localhost"),
(RPC_CSTR)("4747"),
NULL,
(RPC_CSTR*)&szStringBinding);
if(status){
printf("StringBinding failed\n");
exit(status);}
printf("szString=%s\n",szStringBinding);
status=RpcBindingFromStringBinding(
szStringBinding,
&hwBinding);
if(status){
printf("Bind from String failed:%d\n",GetLastError());
exit(status);}
RpcTryExcept{
Hello(hwBinding,(RPC_CSTR)("Hello RPC World!"));
}
RpcExcept(1){
printf("Runtime reported exception:%d,except=%d\n",GetLastError(),RpcExceptionCode()/*RPC_S_ACCESS_DENIED==5L*/);//这里返回了5
}
RpcEndExcept
status = RpcBindingFree(&hwBinding); // Frees the binding handle.
if (status){
printf("Bind free failed\n");
exit(status);}
return 0;
}
void* __RPC_USER midl_user_allocate(size_t size){
return malloc(size);
}
// Memory deallocation function for RPC.
void __RPC_USER midl_user_free(void* p){
free(p);
}
|
运行显示:
szString=ncacn_ip_tcp:localhost[4747]
此时,服务器端显示:
server:Hello RPC World!
多次启动客户端,上面这句话显示多次。
---------------------------------------------------------
自己写的com客户端的代码,放到blog里面作为备份。
-
#include<algorithm>
-
#include<cassert>
-
#include<type_traits>
-
#include<iostream>
-
#include<iterator>
-
using namespace std;
-
-
#import "..\ATLProject1\Debug\ATLProject1.tlb" no_namespace raw_native_types named_guids
-
#import "..\ATLProject3\Debug\ATLProject3.tlb" no_namespace raw_native_types named_guids
-
#import "..\ATLProject5\Debug\ATLProject5.tlb" no_namespace raw_native_types named_guids
-
#import "..\cs_ClassLibrary1\bin\Debug\cs_ClassLibrary1.tlb" no_namespace raw_native_types named_guids
-
-
void UseCSharpCom()
-
{
-
MyCom_InterfacePtr p(CLSID_Class1,NULL,CLSCTX_ALL);
-
printf("%d\n",p->Add(3,9));
-
p.Release();
-
}
-
-
void UsingGeneratedPtr()
-
{
-
IMyErrPtr p(CLSID_MyErr,NULL,CLSCTX_ALL);
-
LONG ret;
-
HRESULT r=p->Sub(&ret,33,48);
-
printf("%d\n",ret);
-
p.Release();
-
}
-
-
void fv(){}
-
short fs(){return 0;}
-
int fi(){return 0;}
-
double fd(){return 0;}
-
int (*pfi);
-
short (*pfs);
-
using namespace std;
-
-
template <class T, size_t n>
-
char (*pc(T (&arr)[n]))[n];
-
-
void ApiDispatch()
-
{
-
CLSID id;
-
HRESULT hr=CLSIDFromProgID(L"my.fun",&id);
-
assert( SUCCEEDED( hr ) );
-
-
CoInitialize(NULL);
-
-
IDispatch* pDisp=NULL;
-
hr=CoCreateInstance(id,NULL,CLSCTX_ALL,IID_IDispatch,(void**)&pDisp);
-
assert( SUCCEEDED( hr ) );
-
-
LPOLESTR pstrName=L"Add";
-
DISPID fID(0);
-
hr=pDisp->GetIDsOfNames(IID_NULL,&pstrName,1,LOCALE_SYSTEM_DEFAULT,&fID);
-
assert( SUCCEEDED( hr ) );
-
-
VARIANT v[2],vResult;
-
v[0].vt=VT_I4;
-
v[1].vt=VT_I4;
-
-
v[0].lVal=33;
-
v[1].lVal=48;
-
DISPPARAMS param={v,NULL,2,0};
-
hr=pDisp->Invoke(fID,IID_NULL,LOCALE_SYSTEM_DEFAULT,DISPATCH_METHOD,¶m,&vResult,NULL,NULL);
-
assert( SUCCEEDED( hr ) );
-
printf("result=%d\n",vResult.lVal);
-
-
pDisp->Release();
-
CoUninitialize();
-
}
-
-
void ATLDispatch()
-
{
-
CLSID id;
-
HRESULT hr=CLSIDFromProgID(L"my.fun",&id);
-
assert( SUCCEEDED( hr ) );
-
-
CoInitialize(NULL);
-
CComDispatchDriver spDisp;
-
hr=CoCreateInstance(id,NULL,CLSCTX_ALL,IID_IUnknown,(void**)&spDisp);
-
assert( SUCCEEDED( hr ) );
-
CComVariant v[3],vResult;
-
v[0]=33;
-
v[1]=48;
-
v[2]=2;
-
hr=spDisp.InvokeN(L"Add3",v,3,&vResult);
-
assert( SUCCEEDED( hr ) );
-
printf("result=%d\n",vResult.lVal);
-
spDisp.Release();
-
CoUninitialize();
-
}
-
-
void f()
-
{
-
//
-
// 1,2
-
// 11,22
-
// 31,32
-
// 41,42
-
// 51,52
-
//
-
-
#define dim 2
-
SAFEARRAYBOUND b[dim];
-
b[0].cElements=5;
-
b[0].lLbound=0;
-
b[1].cElements=2;
-
b[1].lLbound=0;
-
SAFEARRAY* psa=SafeArrayCreate(VT_I4,dim,b);
-
long Idx[dim];
-
int x=0;
-
for(size_t i=0;i<5;++i)
-
{
-
for(size_t j=0;j<2;++j)
-
{
-
Idx[0]=i;
-
Idx[1]=j;
-
x=i*10+j+1;
-
SafeArrayPutElement(psa,Idx,&x);
-
}
-
}
-
int* pi=0;;
-
HRESULT hr=SafeArrayAccessData(psa,(void**)&pi);
-
copy(pi,pi+10,ostream_iterator<int>(cout,","));
-
SafeArrayUnaccessData(psa);
-
SafeArrayDestroy(psa);
-
}
-
-
class CSink: public ICallBack
-
{
-
public:
-
STDMETHODIMP QueryInterface(const struct _GUID&iid,void**ppv)
-
{
-
*ppv=this;
-
return S_OK;
-
}
-
ULONG __stdcall AddRef(void) {return 1;}
-
ULONG __stdcall Release(void){return 0;}
-
STDMETHODIMP raw_Fire_Result(long nResult)
-
{
-
cout<<"fire"<<nResult<<endl;
-
return S_OK;
-
}
-
};
-
-
void UseEventClient()
-
{
-
cout<<__FUNCTION__<<endl;
-
CComQIPtr<IEvent1> pe;
-
pe.CoCreateInstance(CLSID_Event1,NULL,CLSCTX_ALL);
-
if(pe)
-
{
-
cout<<"Call com event"<<endl;
-
CSink client1;
-
ULONG cookie=30;
-
pe->Register(&client1,&cookie);
-
pe->Add(33,99);
-
pe->Unregister(cookie);
-
}
-
pe.Release();
-
}
-
-
void UseSafeArray()
-
{
-
CComSafeArray<int> a(2,0);
-
CComSafeArrayBound bounds[]={(2,0),(3,0),(4,0)};
-
CComSafeArray<int> sa(bounds,_countof(bounds));
-
long index[]={3,2,1};
-
sa.MultiDimSetAt(index,200);
-
}
-
-
IFunPtr pf;
-
UINT __stdcall mytf(void* pArg)
-
{
-
cout<<"Thread function"<<endl;
-
CoInitialize(NULL);
-
-
HRESULT hr=pf.CreateInstance(CLSID_Fun,NULL);//,CLSCTX_REMOTE_SERVER);
-
cout<<pf->Add(2,3)<<endl;
-
Sleep(2000);
-
cout<<"Thread ends"<<endl;
-
pf.Release();
-
CoUninitialize();
-
_endthreadex(0);
-
return 0;
-
}
-
-
void f3()
-
{
-
//_beginthreadex(NULL,0,mytf,NULL,0,NULL);//如何Join?
-
CoInitialize(NULL);
-
IFun* p1,*p2;
-
HRESULT hr=::CoCreateInstance(CLSID_Fun,NULL,CLSCTX_ALL,IID_IFun,(void**)&p1);
-
hr=::CoCreateInstance(CLSID_Fun,NULL,CLSCTX_ALL,IID_IFun,(void**)&p2);
-
assert(p1!=p2);
-
p2->Release();
-
p1->Release();
-
CoUninitialize();
-
}
-
-
class Father
-
{
-
public:
-
int i;
-
Father(){i=22;}
-
virtual void f(){printf("f:%d\n",i);}
-
virtual void g(){printf("g:%d\n",i);}
-
virtual void h(){printf("h:%d\n",i);}
-
};
-
class Child:public Father
-
{
-
public:
-
void f(){printf("child f\n");}
-
};
-
typedef void (__thiscall *pFather)(Father*);
-
void fVTable()
-
{
-
Father* pf=new Father;
-
Father* pf2=new Father;
-
pf->f();
-
printf("pf =%p\npf->i=%p\n",pf,&(pf->i));
-
pFather *pVtable=*(pFather**)(pf);
-
pVtable[0](pf);
-
pVtable[1](pf);
-
pVtable[2](pf);
-
delete pf;
-
delete pf2;
-
-
Father* pc=new Child;
-
printf("Father vtable=%p,%p\nChild vtable=%p\n",
-
*(int*)(pf),
-
*(int*)(pf2),
-
*(int*)(pc));
-
(*(pFather**)(pc))[0](pc);
-
}
-
-
void UsingISupportError(bool fThrowException=false)
-
{
-
IMyErrPtr p(CLSID_MyErr,NULL,CLSCTX_ALL);
-
try
-
{
-
HRESULT hr;
-
if(fThrowException)
-
{
-
LONG ret=0;
-
hr=p->Sub(&ret,33,81);//ATL CComCoClass::Error will throw an exception
-
printf("%d\n",ret);
-
}
-
else
-
{
-
hr=p->raw_Sub2(LONG());
-
CComQIPtr<ISupportErrorInfo> spSEI=p;
-
if(spSEI)
-
{
-
puts("support!");
-
hr=spSEI->InterfaceSupportsErrorInfo(IID_IMyErr);
-
if(SUCCEEDED(hr))
-
{
-
CComQIPtr<IErrorInfo> spError;
-
hr=GetErrorInfo(0,&spError);
-
if(SUCCEEDED(hr))
-
{
-
CComBSTR bstr;
-
spError->GetDescription(&bstr);
-
LPWSTR s1=bstr;
-
LPCTSTR s2=OLE2CT(s1);
-
_tprintf(_T("%s\n"),s2);
-
}
-
}
-
}
-
spSEI.Release();
-
}
-
}
-
catch(_com_error &e)
-
{
-
LPWSTR s=e.Description();
-
_tprintf(_T("%s\n"),OLE2CT(s));
-
}
-
p.Release();
-
}
-
-
void UseCComSafeArray()
-
{
-
CComSafeArrayBound bounds[]={CComSafeArrayBound(2,0),CComSafeArrayBound(3,0),CComSafeArrayBound(4,0)};
-
CComSafeArray<int> arr(bounds,_countof(bounds));
-
SAFEARRAY* psa=arr.m_psa;
-
cout<<psa->cbElements<<','<<psa->cDims<<endl;
-
cout<<arr.GetCount(0)<<','<<arr.GetCount(1)<<','<<arr.GetCount(2)<<endl;
-
CComVariant v=psa;//::SafeArrayCopy() is called
-
}
-
/*
-
void MFCDispatch()
-
{
-
CoInitialize(NULL);
-
CFun f;
-
f.CreateDispatch(L"my.fun");
-
printf("%d\n",f.Add(33,48));
-
f.ReleaseDispatch();
-
CoUninitialize();
-
}
-
*/
-
class CPropertyBag: public IPropertyBag
-
{
-
public:
-
STDMETHODIMP CPropertyBag::QueryInterface(const struct _GUID &iid,void ** ppv)
-
{
-
*ppv = this;
-
return S_OK;
-
}
-
STDMETHODIMP_(ULONG) CPropertyBag::AddRef(void) {return 1;}
-
STDMETHODIMP_(ULONG) CPropertyBag::Release(void){return 0;}
-
STDMETHODIMP CPropertyBag::Read(LPCOLESTR pszPropName,VARIANT *pVar,IErrorLog *pErrorLog)
-
{
-
cout<<__FUNCTION__<<','<<pVar->vt<<endl;
-
if( pVar->vt == VT_BSTR )
-
{
-
pVar->bstrVal=OLE2BSTR(L"mystring");
-
return S_OK;
-
}
-
else if( pVar->vt == VT_I4 )
-
{
-
pVar->lVal=207;
-
return S_OK;
-
}
-
else return E_FAIL;
-
}
-
STDMETHODIMP CPropertyBag::Write(LPCOLESTR pszPropName,VARIANT *pVar)
-
{
-
return S_OK;
-
}
-
};
-
void UsePropBag()
-
{
-
IPersistPropertyBagPtr ptr(CLSID_Property,NULL,CLSCTX_ALL);
-
if(ptr)
-
{
-
CPropertyBag bag;
-
ptr->Load(&bag,NULL);
-
ptr.Release();
-
}
-
}
-
-
void UseAggregation()
-
{
-
IMyAggrPtr sp1(CLSID_MyAggr,NULL,CLSCTX_ALL);
-
IFooPtr spFoo;
-
sp1->QueryInterface(&spFoo);
-
cout<<spFoo->Add(3,4)<<endl;
-
spFoo.Release();
-
sp1.Release();
-
}
-
-
class CPSink : public IDispatch
-
{
-
public:
-
STDMETHODIMP QueryInterface(const struct _GUID &iid,void ** ppv)
-
{
-
*ppv=this;
-
return S_OK;
-
}
-
STDMETHODIMP_(ULONG) AddRef(void){return 1;}
-
STDMETHODIMP_(ULONG) Release(void){return 0;}
-
STDMETHODIMP GetTypeInfoCount(unsigned int *){return E_NOTIMPL;}
-
STDMETHODIMP GetTypeInfo(unsigned int,unsigned long,struct ITypeInfo ** ){return E_NOTIMPL;}
-
STDMETHODIMP GetIDsOfNames(const IID &,LPOLESTR *,UINT,LCID,DISPID *){return E_NOTIMPL;}
-
STDMETHODIMP Invoke(
-
long dispID,
-
const struct _GUID &,
-
unsigned long,
-
unsigned short,
-
struct tagDISPPARAMS * pParams,
-
struct tagVARIANT *,
-
struct tagEXCEPINFO *,
-
unsigned int *)
-
{
-
switch(dispID)
-
{
-
case 1:
-
_tprintf(_T("Result=%d\n"),pParams->rgvarg[0].lVal);
-
break;
-
default:
-
break;
-
}
-
return S_OK;
-
}
-
};
-
-
void TestConnectionPoint()
-
{
-
ICP1Ptr spCP1(CLSID_CP1,NULL,CLSCTX_ALL);
-
CComQIPtr<IConnectionPointContainer> spContainer=spCP1;
-
CComQIPtr<IConnectionPoint> spCP;
-
HRESULT hr=spContainer->FindConnectionPoint(DIID__ICP1Events,&spCP);
-
CPSink obj;
-
DWORD dwCookie;
-
spCP->Advise(&obj,&dwCookie);
-
spCP1->Add(3,9);
-
spCP->Unadvise(dwCookie);
-
spCP.Release();
-
spContainer.Release();
-
spCP1.Release();
-
}
-
-
struct UseStream
-
{
-
HRESULT hr; // 函数执行返回值
-
IStorage *pStg;
-
IStorage *pSub;
-
IStream *pStm;
-
UseStream()
-
{
-
IStorage *pStg = NULL; // 根存储接口指针
-
IStorage *pSub = NULL; // 子存储接口指针
-
IStream *pStm = NULL; // 流接口指针
-
CreateDoc();
-
}
-
~UseStream()
-
{
-
CloseDoc();
-
}
-
void CreateDoc()
-
{
-
hr = ::StgCreateDocfile( // 建立复合文件
-
L"d:\\c.stg", // 文件名称
-
STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, // 打开方式
-
0, // 保留参数
-
&pStg); // 取得根存储接口指针
-
assert( SUCCEEDED(hr) ); // 为了突出重点,简化程序结构,所以使用了断言。
-
// 在实际的程序中则要使用条件判断和异常处理
-
-
hr = pStg->CreateStorage( // 建立子存储
-
L"SubStg", // 子存储名称
-
STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,
-
0,0,
-
&pSub); // 取得子存储接口指针
-
assert( SUCCEEDED(hr) );
-
-
hr = pSub->CreateStream( // 建立流
-
L"Stm", // 流名称
-
STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,
-
0,0,
-
&pStm); // 取得流接口指针
-
assert( SUCCEEDED(hr) );
-
}
-
void CloseDoc()
-
{
-
if( pStm ) pStm->Release();// 释放流指针
-
if( pSub ) pSub->Release();// 释放子存储指针
-
if( pStg ) pStg->Release();// 释放根存储指针
-
}
-
void WriteSample()
-
{
-
hr = pStm->Write( // 向流中写入数据
-
"Hello", // 数据地址
-
5, // 字节长度(注意,没有写入字符串结尾的\0)
-
NULL); // 不需要得到实际写入的字节长度
-
assert( SUCCEEDED(hr) );
-
-
IPersistStreamInitPtr spStream(CLSID_MySingle,NULL,CLSCTX_ALL);
-
if(spStream)
-
{
-
spStream->InitNew();
-
spStream->Save(pStm,TRUE);
-
spStream.Release();
-
}
-
}
-
void WriteMarshalToDocument()
-
{
-
IFunPtr ptr(CLSID_Fun,NULL,CLSCTX_ALL);
-
assert(ptr);
-
CoMarshalInterface(pStm,IID_IFun,ptr,MSHCTX_LOCAL,NULL,MSHLFLAGS_NORMAL);
-
ptr.Release();
-
}
-
};
-
-
void SampleCreateDoc()
-
{
-
UseStream obj1;
-
obj1.WriteMarshalToDocument();
-
}
-
-
void MarshalOleAutomation()
-
{
-
IE2Ptr ptr(CLSID_E2,NULL,CLSCTX_ALL);
-
assert(ptr);
-
IStream* pStm;
-
HRESULT hr = CoMarshalInterThreadInterfaceInStream(IID_IE2,ptr,&pStm);
-
assert(SUCCEEDED(hr));
-
IE2Ptr pGet;
-
hr=CoGetInterfaceAndReleaseStream(pStm,IID_IE2,(LPVOID*)&pGet);
-
assert(SUCCEEDED(hr));
-
cout<<pGet->Add(44,3)<<endl;//自定义接口+支持oleautomation
-
ptr.Release();
-
}
-
-
class WriteMarshalToMemory
-
{
-
static IStream* pStm;
-
public:
-
static DWORD WINAPI f(void*)
-
{
-
CoInitialize(NULL);
-
IE2Ptr pGet;
-
HRESULT hr=CoGetInterfaceAndReleaseStream(pStm,IID_IE2,(LPVOID*)&pGet);
-
assert(SUCCEEDED(hr));
-
cout<<pGet->Add(44,29)<<endl;
-
CoUninitialize();
-
return 0;
-
}
-
WriteMarshalToMemory()
-
{
-
IE2Ptr ptr(CLSID_E2,NULL,CLSCTX_ALL);
-
assert(ptr);
-
HRESULT hr = CoMarshalInterThreadInterfaceInStream(IID_IE2,ptr,&pStm);
-
assert(SUCCEEDED(hr));
-
-
HANDLE hThread=CreateThread(NULL,size_t(),f,NULL,DWORD(),NULL);
-
WaitForSingleObject(hThread,INFINITE);
-
ptr.Release();
-
}
-
};
-
IStream* WriteMarshalToMemory::pStm = NULL;
-
-
IStream* g_pStm;
-
DWORD WINAPI tf(void*)
-
{
-
CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
-
IMy1Ptr pGet;
-
HRESULT hr=CoGetInterfaceAndReleaseStream(g_pStm,IID_IMy1,(LPVOID*)&pGet);
-
assert(SUCCEEDED(hr));
-
long ret=pGet->Add(44,29);
-
cout<<ret<<endl;
-
CoUninitialize();
-
return 0;
-
}
-
void TestMarshal()
-
{
-
CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
-
IMy1Ptr ptr(CLSID_My1,NULL,CLSCTX_ALL);
-
assert(ptr);
-
HRESULT hr = CoMarshalInterThreadInterfaceInStream(IID_IMy1,ptr,&g_pStm);
-
assert(SUCCEEDED(hr));
-
HANDLE hThread=CreateThread(NULL,0,tf,NULL,0,NULL);
-
Sleep(10000);//子线程调用STA主线程创建的com对象,需要用到主线程的消息队列
-
MessageBox(0, _T(""), _T(""), 0);//MessageBox显示的时候创建消息队列,点击OK的时候关闭消息队列
-
WaitForSingleObject(hThread,INFINITE);
-
ptr.Release();
-
CoUninitialize();
-
}
-
-
void UseMyStruct()
-
{
-
IE3Ptr ptr(CLSID_E3,NULL,CLSCTX_ALL);
-
My obj={2,"xyz"};
-
ptr->SetMy(&obj);
-
MyStruct ms={1,2};
-
ptr->SetMyStruct(&ms);
-
ptr->GetMy(&obj);
-
cout<<obj.m_i<<obj.m_str<<endl;
-
ptr.Release();
-
}
-
-
void UseClassFactory()
-
{
-
IClassFactory *pFactory=nullptr;
-
HRESULT hr=CoGetClassObject(CLSID_My1,CLSCTX_ALL,NULL,IID_IClassFactory,(void**)&pFactory);
-
IMy1* pMy1=nullptr;
-
hr=pFactory->CreateInstance(NULL,IID_IMy1,(void**)&pMy1);
-
cout<<pMy1->Add(3,3)<<endl;
-
pMy1->Release();
-
pFactory->Release();
-
}
ClassFactory的用法如下。
-
int main(void)
-
{
-
VARIANT var,var2;
-
VariantInit(&var);
-
VariantInit(&var2);
-
-
V_VT(&var)=VT_I4;
-
V_I4(&var)=20;
-
-
VariantChangeType(&var2,&var,VARIANT_NOVALUEPROP,VT_BSTR);
-
_tprintf(var2.bstrVal);
-
-
VariantClear(&var);
-
VariantClear(&var2);
-
-
CoInitialize(NULL);
-
IClassFactory* pf=NULL;
-
HRESULT hr=CoGetClassObject(CLSID_Bar,CLSCTX_ALL,NULL,IID_IClassFactory,(void**)&pf);
-
IBar* pBar=NULL;
-
hr=pf->CreateInstance(NULL,IID_IBar,(void**)&pBar);
-
if(pBar)pBar->Release();
-
pf->Release();
-
-
IClassFactory2* pf2=NULL;
-
hr=CoGetClassObject(CLSID_Bar,CLSCTX_ALL,NULL,IID_IClassFactory2,(void**)&pf2);
-
IBar* pBar2=NULL;
-
BSTR bstrKey;
-
hr=pf2->RequestLicKey(DWORD(),&bstrKey);
-
hr=pf2->CreateInstanceLic(NULL,NULL,IID_IBar,bstrKey,(void**)&pBar2);
-
if(pBar2)pBar2->Release();
-
pf2->Release();
-
CoUninitialize();
-
return 0;
-
}
阅读(8419) | 评论(1) | 转发(2) |