COM组件已经部署好了,接下来就是调用了既然我们是部署了COM+服务器,我们这里就讲下怎么远程调用COM组件。
在创建好VC的WIN32项目后,在预编译文件中引用。
- #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
- #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
- #endif
- #include
- #include
- #include
- #include
- #include
- #import "SayHello.tlb" no_namespace named_guids
#define _WIN32_WINNT 0x0501 //是为了DCOM调用很多函数都有下面的限定,不然不能编译通过了如:
#if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) // DCOM
#import "SayHello.tlb" no_namespace named_guids //是将COM组件的定义引用进来
ISayHello接口变为C++的如下定义:
- struct __declspec(uuid("c6d664f5-6cf6-4c12-9948-8a40b16818be"))
- ISayHello : IDispatch
- {
- //
- // Wrapper methods for error-handling
- //
- _bstr_t SayHello (
- _bstr_t name );
- //
- // Raw methods provided by interface
- //
- virtual HRESULT __stdcall raw_SayHello (
- /*[in]*/ BSTR name,
- /*[out,retval]*/ BSTR * pRetVal ) = 0;
- };
调用代码如下:
- //初始化COM运行环境,也可以使用CoInitialize但使用COM的每根线程都需要调用
- CoInitializeEx(NULL, COINIT_MULTITHREADED);
- HRESULT hr;
- //为进程(一个进程只需调用一次)注册安全和设置默认安全设置,
- //我们上期写的是以匿名方式部署可以不需要这部分
- hr = CoInitializeSecurity(NULL, -1, NULL, NULL,RPC_C_AUTHN_LEVEL_NONE,
- RPC_C_IMP_LEVEL_ANONYMOUS, NULL, EOAC_NONE, NULL);
- // //设置验证标识信息,我们上期写的是以匿名方式部署不需要这部分
- // COAUTHIDENTITY *pAuthidentity;
- // COAUTHINFO *pAuthInfo;
- // pAuthidentity = (COAUTHIDENTITY*)malloc(sizeof(COAUTHIDENTITY));
- // pAuthidentity->User = (USHORT*)pUser;
- // pAuthidentity->UserLength = strlen(pUser);
- // pAuthidentity->Password = (USHORT*)pPassword;
- // pAuthidentity->PasswordLength = strlen(pPassword);
- // pAuthidentity->Domain = NULL;
- // pAuthidentity->DomainLength = 0;
- // //有时候验证通过UNICODE的方式不要设置错了
- // pAuthidentity->Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
- //
- // //验证信息
- // pAuthInfo = (COAUTHINFO*)malloc(sizeof(COAUTHINFO));
- // pAuthInfo->dwAuthnSvc= RPC_C_AUTHN_WINNT;
- // pAuthInfo->dwAuthzSvc= RPC_C_AUTHZ_NONE;
- // pAuthInfo->pwszServerPrincName= NULL;
- // pAuthInfo->dwAuthnLevel= RPC_C_AUTHN_LEVEL_NONE;
- // pAuthInfo->dwImpersonationLevel= RPC_C_IMP_LEVEL_IMPERSONATE;
- // pAuthInfo->dwCapabilities= RPC_C_QOS_CAPABILITIES_DEFAULT;
- // pAuthInfo->pAuthIdentityData= pAuthidentity;
- //远程服务器信息
- COSERVERINFO ServerInfo={0, L"192.168.0.200", NULL/*pAuthInfo*/, 0};
- MULTI_QI MultiQi={ IID_ISayHello, NULL, NOERROR };
- ISayHello *pSayHello;
- //创建DCOM对象返回接口指针
- hr = CoCreateInstanceEx(CLSID_CSayHello, NULL, CLSCTX_REMOTE_SERVER, &ServerInfo, 1, &MultiQi);
- if(FAILED(hr)) return;
- *pSayHello = (ISayHello*)MultiQi.pItf;
- //为DCOM对象指针设置反问安全令牌
- hr = CoSetProxyBlanket(*ppUnknown, RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE, NULL,
- RPC_C_AUTHN_LEVEL_NONE,RPC_C_IMP_LEVEL_ANONYMOUS, NULL/*pAuthidentity*/, EOAC_NONE);
- BSTR userName = SysAllocString(L"test");
- BSTR retVal;
- //调用DCOM接口
- hr = pSayHello->raw_SayHello(userName, &retVal);
- //释放DCOM接口
- pSayHello->Release();
- //释放COM运行环境
- CoUninitialize();