COM与.NET调用DCOM组件

来源:互联网 发布:java获取浏览器语言 编辑:程序博客网 时间:2024/05/22 01:47
COM组件已经部署好了,接下来就是调用了既然我们是部署了COM+服务器,我们这里就讲下怎么远程调用COM组件。

在创建好VC的WIN32项目后,在预编译文件中引用。

  1. #ifndef _WIN32_WINNT    // Allow use of features specific to Windows XP or later.                   
  2. #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
  3. #endif                      

  4. #include <stdio.h>
  5. #include <tchar.h>
  6. #include <icrsint.h>
  7. #include <iostream>
  8. #include <windows.h>

  9. #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++的如下定义:

  1. struct __declspec(uuid("c6d664f5-6cf6-4c12-9948-8a40b16818be"))
  2. ISayHello : IDispatch
  3. {
  4.     //
  5.     // Wrapper methods for error-handling
  6.     //
  7.     _bstr_t SayHello (
  8.         _bstr_t name );

  9.     //
  10.     // Raw methods provided by interface
  11.     //

  12.     virtual HRESULT __stdcall raw_SayHello (
  13.         /*[in]*/ BSTR name,
  14.         /*[out,retval]*/ BSTR * pRetVal ) = 0;
  15. };

调用代码如下:

  1.     //初始化COM运行环境,也可以使用CoInitialize但使用COM的每根线程都需要调用
  2.     CoInitializeEx(NULL, COINIT_MULTITHREADED);
  3.     HRESULT hr;
  4.     //为进程(一个进程只需调用一次)注册安全和设置默认安全设置,
  5.     //我们上期写的是以匿名方式部署可以不需要这部分
  6.     hr = CoInitializeSecurity(NULL, -1, NULL, NULL,RPC_C_AUTHN_LEVEL_NONE, 
  7.         RPC_C_IMP_LEVEL_ANONYMOUS, NULL, EOAC_NONE, NULL);
  8.     
  9. //  //设置验证标识信息,我们上期写的是以匿名方式部署不需要这部分
  10. //  COAUTHIDENTITY *pAuthidentity;
  11. //  COAUTHINFO *pAuthInfo;
  12. //  pAuthidentity = (COAUTHIDENTITY*)malloc(sizeof(COAUTHIDENTITY));
  13. //  pAuthidentity->User = (USHORT*)pUser;
  14. //  pAuthidentity->UserLength = strlen(pUser);
  15. //  pAuthidentity->Password = (USHORT*)pPassword;
  16. //  pAuthidentity->PasswordLength = strlen(pPassword);
  17. //  pAuthidentity->Domain = NULL;
  18. //  pAuthidentity->DomainLength = 0;
  19. //  //有时候验证通过UNICODE的方式不要设置错了
  20. //  pAuthidentity->Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  21. //  
  22. //  //验证信息
  23. //  pAuthInfo = (COAUTHINFO*)malloc(sizeof(COAUTHINFO));
  24. //  pAuthInfo->dwAuthnSvc= RPC_C_AUTHN_WINNT;
  25. //  pAuthInfo->dwAuthzSvc= RPC_C_AUTHZ_NONE;
  26. //  pAuthInfo->pwszServerPrincName= NULL;
  27. //  pAuthInfo->dwAuthnLevel= RPC_C_AUTHN_LEVEL_NONE;
  28. //  pAuthInfo->dwImpersonationLevel= RPC_C_IMP_LEVEL_IMPERSONATE;
  29. //  pAuthInfo->dwCapabilities= RPC_C_QOS_CAPABILITIES_DEFAULT;
  30. //  pAuthInfo->pAuthIdentityData= pAuthidentity;

  31.     //远程服务器信息
  32.     COSERVERINFO ServerInfo={0, L"192.168.0.200", NULL/*pAuthInfo*/, 0};
  33.     MULTI_QI MultiQi={ IID_ISayHello, NULL, NOERROR };
  34.     ISayHello *pSayHello;
  35.     //创建DCOM对象返回接口指针
  36.     hr = CoCreateInstanceEx(CLSID_CSayHello, NULL, CLSCTX_REMOTE_SERVER, &ServerInfo, 1, &MultiQi);
  37.     if(FAILED(hr)) return;
  38.     
  39.     *pSayHello = (ISayHello*)MultiQi.pItf;
  40.     //为DCOM对象指针设置反问安全令牌
  41.     hr = CoSetProxyBlanket(*ppUnknown, RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE, NULL,
  42.         RPC_C_AUTHN_LEVEL_NONE,RPC_C_IMP_LEVEL_ANONYMOUS, NULL/*pAuthidentity*/, EOAC_NONE);

  43.     BSTR userName = SysAllocString(L"test");
  44.     BSTR retVal;
  45.     //调用DCOM接口
  46.     hr = pSayHello->raw_SayHello(userName, &retVal);
  47.     //释放DCOM接口
  48.     pSayHello->Release();
  49.     //释放COM运行环境
  50.     CoUninitialize();
0 0