Chinaunix首页 | 论坛 | 博客
  • 博客访问: 141710
  • 博文数量: 10
  • 博客积分: 2431
  • 博客等级: 大尉
  • 技术积分: 266
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-02 00:56
文章分类
文章存档

2016年(1)

2013年(2)

2011年(3)

2010年(4)

分类: C/C++

2010-10-15 21:15:44

    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里面作为备份。

点击(此处)折叠或打开

  1. #include<algorithm>
  2. #include<cassert>
  3. #include<type_traits>
  4. #include<iostream>
  5. #include<iterator>
  6. using namespace std;

  7. #import "..\ATLProject1\Debug\ATLProject1.tlb" no_namespace raw_native_types named_guids
  8. #import "..\ATLProject3\Debug\ATLProject3.tlb" no_namespace raw_native_types named_guids
  9. #import "..\ATLProject5\Debug\ATLProject5.tlb" no_namespace raw_native_types named_guids
  10. #import "..\cs_ClassLibrary1\bin\Debug\cs_ClassLibrary1.tlb" no_namespace raw_native_types named_guids

  11. void UseCSharpCom()
  12. {
  13.     MyCom_InterfacePtr p(CLSID_Class1,NULL,CLSCTX_ALL);
  14.     printf("%d\n",p->Add(3,9));
  15.     p.Release();
  16. }

  17. void UsingGeneratedPtr()
  18. {
  19.     IMyErrPtr p(CLSID_MyErr,NULL,CLSCTX_ALL);
  20.     LONG ret;
  21.     HRESULT r=p->Sub(&ret,33,48);
  22.     printf("%d\n",ret);
  23.     p.Release();
  24. }

  25. void fv(){}
  26. short fs(){return 0;}
  27. int fi(){return 0;}
  28. double fd(){return 0;}
  29. int (*pfi);
  30. short (*pfs);
  31. using namespace std;

  32. template <class T, size_t n>
  33. char (*pc(T (&arr)[n]))[n];

  34. void ApiDispatch()
  35. {
  36.     CLSID id;
  37.     HRESULT hr=CLSIDFromProgID(L"my.fun",&id);
  38.     assert( SUCCEEDED( hr ) );

  39.     CoInitialize(NULL);

  40.     IDispatch* pDisp=NULL;
  41.     hr=CoCreateInstance(id,NULL,CLSCTX_ALL,IID_IDispatch,(void**)&pDisp);
  42.     assert( SUCCEEDED( hr ) );

  43.     LPOLESTR pstrName=L"Add";
  44.     DISPID fID(0);
  45.     hr=pDisp->GetIDsOfNames(IID_NULL,&pstrName,1,LOCALE_SYSTEM_DEFAULT,&fID);
  46.     assert( SUCCEEDED( hr ) );

  47.     VARIANT v[2],vResult;
  48.     v[0].vt=VT_I4;
  49.     v[1].vt=VT_I4;

  50.     v[0].lVal=33;
  51.     v[1].lVal=48;
  52.     DISPPARAMS param={v,NULL,2,0};
  53.     hr=pDisp->Invoke(fID,IID_NULL,LOCALE_SYSTEM_DEFAULT,DISPATCH_METHOD,&param,&vResult,NULL,NULL);
  54.     assert( SUCCEEDED( hr ) );
  55.     printf("result=%d\n",vResult.lVal);

  56.     pDisp->Release();
  57.     CoUninitialize();
  58. }

  59. void ATLDispatch()
  60. {
  61.     CLSID id;
  62.     HRESULT hr=CLSIDFromProgID(L"my.fun",&id);
  63.     assert( SUCCEEDED( hr ) );

  64.     CoInitialize(NULL);
  65.     CComDispatchDriver spDisp;
  66.     hr=CoCreateInstance(id,NULL,CLSCTX_ALL,IID_IUnknown,(void**)&spDisp);
  67.     assert( SUCCEEDED( hr ) );
  68.     CComVariant v[3],vResult;
  69.     v[0]=33;
  70.     v[1]=48;
  71.     v[2]=2;
  72.     hr=spDisp.InvokeN(L"Add3",v,3,&vResult);
  73.     assert( SUCCEEDED( hr ) );
  74.     printf("result=%d\n",vResult.lVal);
  75.     spDisp.Release();
  76.     CoUninitialize();
  77. }

  78. void f()
  79. {
  80. //
  81. // 1,2
  82. // 11,22
  83. // 31,32
  84. // 41,42
  85. // 51,52
  86. //

  87.     #define dim 2
  88.     SAFEARRAYBOUND b[dim];
  89.     b[0].cElements=5;
  90.     b[0].lLbound=0;
  91.     b[1].cElements=2;
  92.     b[1].lLbound=0;
  93.     SAFEARRAY* psa=SafeArrayCreate(VT_I4,dim,b);
  94.     long Idx[dim];
  95.     int x=0;
  96.     for(size_t i=0;i<5;++i)
  97.     {
  98.         for(size_t j=0;j<2;++j)
  99.         {
  100.             Idx[0]=i;
  101.             Idx[1]=j;
  102.             x=i*10+j+1;
  103.             SafeArrayPutElement(psa,Idx,&x);
  104.         }
  105.     }
  106.     int* pi=0;;
  107.     HRESULT hr=SafeArrayAccessData(psa,(void**)&pi);
  108.     copy(pi,pi+10,ostream_iterator<int>(cout,","));
  109.     SafeArrayUnaccessData(psa);
  110.     SafeArrayDestroy(psa);
  111. }

  112. class CSink: public ICallBack
  113. {
  114. public:
  115.     STDMETHODIMP QueryInterface(const struct _GUID&iid,void**ppv)
  116.     {
  117.         *ppv=this;
  118.         return S_OK;
  119.     }
  120.     ULONG __stdcall AddRef(void) {return 1;}
  121.     ULONG __stdcall Release(void){return 0;}
  122.     STDMETHODIMP raw_Fire_Result(long nResult)
  123.     {
  124.         cout<<"fire"<<nResult<<endl;
  125.         return S_OK;
  126.     }
  127. };

  128. void UseEventClient()
  129. {
  130.     cout<<__FUNCTION__<<endl;
  131.     CComQIPtr<IEvent1> pe;
  132.     pe.CoCreateInstance(CLSID_Event1,NULL,CLSCTX_ALL);
  133.     if(pe)
  134.     {
  135.         cout<<"Call com event"<<endl;
  136.         CSink client1;
  137.         ULONG cookie=30;
  138.         pe->Register(&client1,&cookie);
  139.         pe->Add(33,99);
  140.         pe->Unregister(cookie);
  141.     }
  142.     pe.Release();
  143. }

  144. void UseSafeArray()
  145. {
  146.     CComSafeArray<int> a(2,0);
  147.     CComSafeArrayBound bounds[]={(2,0),(3,0),(4,0)};
  148.     CComSafeArray<int> sa(bounds,_countof(bounds));
  149.     long index[]={3,2,1};
  150.     sa.MultiDimSetAt(index,200);
  151. }

  152. IFunPtr pf;
  153. UINT __stdcall mytf(void* pArg)
  154. {
  155.     cout<<"Thread function"<<endl;
  156.     CoInitialize(NULL);

  157.     HRESULT hr=pf.CreateInstance(CLSID_Fun,NULL);//,CLSCTX_REMOTE_SERVER);
  158.     cout<<pf->Add(2,3)<<endl;
  159.     Sleep(2000);
  160.     cout<<"Thread ends"<<endl;
  161.     pf.Release();
  162.     CoUninitialize();
  163.     _endthreadex(0);
  164.     return 0;
  165. }

  166. void f3()
  167. {
  168.     //_beginthreadex(NULL,0,mytf,NULL,0,NULL);//如何Join?
  169.     CoInitialize(NULL);
  170.     IFun* p1,*p2;
  171.     HRESULT hr=::CoCreateInstance(CLSID_Fun,NULL,CLSCTX_ALL,IID_IFun,(void**)&p1);
  172.     hr=::CoCreateInstance(CLSID_Fun,NULL,CLSCTX_ALL,IID_IFun,(void**)&p2);
  173.     assert(p1!=p2);
  174.     p2->Release();
  175.     p1->Release();
  176.     CoUninitialize();
  177. }

  178. class Father
  179. {
  180. public:
  181.     int i;
  182.     Father(){i=22;}
  183.     virtual void f(){printf("f:%d\n",i);}
  184.     virtual void g(){printf("g:%d\n",i);}
  185.     virtual void h(){printf("h:%d\n",i);}
  186. };
  187. class Child:public Father
  188. {
  189. public:
  190.     void f(){printf("child f\n");}
  191. };
  192. typedef void (__thiscall *pFather)(Father*);
  193. void fVTable()
  194. {
  195.     Father* pf=new Father;
  196.     Father* pf2=new Father;
  197.     pf->f();
  198.     printf("pf =%p\npf->i=%p\n",pf,&(pf->i));
  199.     pFather *pVtable=*(pFather**)(pf);
  200.     pVtable[0](pf);
  201.     pVtable[1](pf);
  202.     pVtable[2](pf);
  203.     delete pf;
  204.     delete pf2;
  205.     
  206.     Father* pc=new Child;
  207.     printf("Father vtable=%p,%p\nChild vtable=%p\n",
  208.         *(int*)(pf),
  209.         *(int*)(pf2),
  210.         *(int*)(pc));
  211.     (*(pFather**)(pc))[0](pc);
  212. }

  213. void UsingISupportError(bool fThrowException=false)
  214. {
  215.     IMyErrPtr p(CLSID_MyErr,NULL,CLSCTX_ALL);
  216.     try
  217.     {
  218.         HRESULT hr;
  219.         if(fThrowException)
  220.         {
  221.             LONG ret=0;
  222.             hr=p->Sub(&ret,33,81);//ATL CComCoClass::Error will throw an exception
  223.             printf("%d\n",ret);
  224.         }
  225.         else
  226.         {
  227.             hr=p->raw_Sub2(LONG());
  228.             CComQIPtr<ISupportErrorInfo> spSEI=p;
  229.             if(spSEI)
  230.             {
  231.                 puts("support!");
  232.                 hr=spSEI->InterfaceSupportsErrorInfo(IID_IMyErr);
  233.                 if(SUCCEEDED(hr))
  234.                 {
  235.                     CComQIPtr<IErrorInfo> spError;
  236.                     hr=GetErrorInfo(0,&spError);
  237.                     if(SUCCEEDED(hr))
  238.                     {
  239.                         CComBSTR bstr;
  240.                         spError->GetDescription(&bstr);
  241.                         LPWSTR s1=bstr;
  242.                         LPCTSTR s2=OLE2CT(s1);
  243.                         _tprintf(_T("%s\n"),s2);
  244.                     }
  245.                 }
  246.             }
  247.             spSEI.Release();
  248.         }
  249.     }
  250.     catch(_com_error &e)
  251.     {
  252.         LPWSTR s=e.Description();
  253.         _tprintf(_T("%s\n"),OLE2CT(s));
  254.     }
  255.     p.Release();
  256. }

  257. void UseCComSafeArray()
  258. {
  259.        CComSafeArrayBound bounds[]={CComSafeArrayBound(2,0),CComSafeArrayBound(3,0),CComSafeArrayBound(4,0)};
  260.     CComSafeArray<int> arr(bounds,_countof(bounds));
  261.     SAFEARRAY* psa=arr.m_psa;
  262.     cout<<psa->cbElements<<','<<psa->cDims<<endl;
  263.     cout<<arr.GetCount(0)<<','<<arr.GetCount(1)<<','<<arr.GetCount(2)<<endl;
  264.     CComVariant v=psa;//::SafeArrayCopy() is called
  265. }
  266. /*
  267. void MFCDispatch()
  268. {
  269.     CoInitialize(NULL);
  270.     CFun f;
  271.     f.CreateDispatch(L"my.fun");
  272.     printf("%d\n",f.Add(33,48));
  273.     f.ReleaseDispatch();
  274.     CoUninitialize();
  275. }
  276. */
  277. class CPropertyBag: public IPropertyBag
  278. {
  279. public:
  280.     STDMETHODIMP CPropertyBag::QueryInterface(const struct _GUID &iid,void ** ppv)
  281.     {
  282.         *ppv = this;
  283.         return S_OK;
  284.     }
  285.     STDMETHODIMP_(ULONG) CPropertyBag::AddRef(void) {return 1;}
  286.     STDMETHODIMP_(ULONG) CPropertyBag::Release(void){return 0;}
  287.     STDMETHODIMP CPropertyBag::Read(LPCOLESTR pszPropName,VARIANT *pVar,IErrorLog *pErrorLog)
  288.     {
  289.         cout<<__FUNCTION__<<','<<pVar->vt<<endl;
  290.         if( pVar->vt == VT_BSTR )
  291.         {
  292.             pVar->bstrVal=OLE2BSTR(L"mystring");
  293.             return S_OK;
  294.         }
  295.         else if( pVar->vt == VT_I4 )
  296.         {
  297.             pVar->lVal=207;
  298.             return S_OK;
  299.         }
  300.         else return E_FAIL;
  301.     }
  302.     STDMETHODIMP CPropertyBag::Write(LPCOLESTR pszPropName,VARIANT *pVar)
  303.     {
  304.         return S_OK;
  305.     }
  306. };
  307. void UsePropBag()
  308. {
  309.     IPersistPropertyBagPtr ptr(CLSID_Property,NULL,CLSCTX_ALL);
  310.     if(ptr)
  311.     {
  312.         CPropertyBag bag;
  313.         ptr->Load(&bag,NULL);
  314.         ptr.Release();
  315.     }
  316. }

  317. void UseAggregation()
  318. {
  319.     IMyAggrPtr sp1(CLSID_MyAggr,NULL,CLSCTX_ALL);
  320.     IFooPtr spFoo;
  321.     sp1->QueryInterface(&spFoo);
  322.     cout<<spFoo->Add(3,4)<<endl;
  323.     spFoo.Release();
  324.     sp1.Release();
  325. }

  326. class CPSink : public IDispatch
  327. {
  328. public:
  329.     STDMETHODIMP QueryInterface(const struct _GUID &iid,void ** ppv)
  330.     {
  331.         *ppv=this;
  332.         return S_OK;
  333.     }
  334.     STDMETHODIMP_(ULONG) AddRef(void){return 1;}
  335.     STDMETHODIMP_(ULONG) Release(void){return 0;}
  336.     STDMETHODIMP GetTypeInfoCount(unsigned int *){return E_NOTIMPL;}
  337.     STDMETHODIMP GetTypeInfo(unsigned int,unsigned long,struct ITypeInfo ** ){return E_NOTIMPL;}
  338.     STDMETHODIMP GetIDsOfNames(const IID &,LPOLESTR *,UINT,LCID,DISPID *){return E_NOTIMPL;}
  339.     STDMETHODIMP Invoke(
  340.         long dispID,
  341.         const struct _GUID &,
  342.         unsigned long,
  343.         unsigned short,
  344.         struct tagDISPPARAMS * pParams,
  345.         struct tagVARIANT *,
  346.         struct tagEXCEPINFO *,
  347.         unsigned int *)
  348.     {
  349.         switch(dispID)
  350.         {
  351.         case 1:
  352.             _tprintf(_T("Result=%d\n"),pParams->rgvarg[0].lVal);
  353.         break;
  354.         default:
  355.             break;
  356.         }
  357.         return S_OK;
  358.     }
  359. };

  360. void TestConnectionPoint()
  361. {
  362.     ICP1Ptr spCP1(CLSID_CP1,NULL,CLSCTX_ALL);
  363.     CComQIPtr<IConnectionPointContainer> spContainer=spCP1;
  364.     CComQIPtr<IConnectionPoint> spCP;
  365.     HRESULT hr=spContainer->FindConnectionPoint(DIID__ICP1Events,&spCP);
  366.     CPSink obj;
  367.     DWORD dwCookie;
  368.     spCP->Advise(&obj,&dwCookie);
  369.     spCP1->Add(3,9);
  370.     spCP->Unadvise(dwCookie);
  371.     spCP.Release();
  372.     spContainer.Release();
  373.     spCP1.Release();
  374. }

  375. struct UseStream
  376. {
  377.     HRESULT hr;        // 函数执行返回值
  378.     IStorage *pStg;
  379.     IStorage *pSub;
  380.     IStream *pStm;
  381.     UseStream()
  382.     {
  383.      IStorage *pStg = NULL;    // 根存储接口指针
  384.      IStorage *pSub = NULL;    // 子存储接口指针
  385.      IStream *pStm = NULL;    // 流接口指针
  386.         CreateDoc();
  387.     }
  388.     ~UseStream()
  389.     {
  390.         CloseDoc();
  391.     }
  392.     void CreateDoc()
  393.     {
  394.      hr = ::StgCreateDocfile(    // 建立复合文件
  395.          L"d:\\c.stg",    // 文件名称
  396.          STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,    // 打开方式
  397.          0,        // 保留参数
  398.          &pStg);        // 取得根存储接口指针
  399.      assert( SUCCEEDED(hr) );    // 为了突出重点,简化程序结构,所以使用了断言。
  400.                  // 在实际的程序中则要使用条件判断和异常处理

  401.      hr = pStg->CreateStorage(    // 建立子存储
  402.          L"SubStg",    // 子存储名称
  403.          STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,
  404.          0,0,
  405.          &pSub);        // 取得子存储接口指针
  406.      assert( SUCCEEDED(hr) );

  407.      hr = pSub->CreateStream(    // 建立流
  408.          L"Stm",        // 流名称
  409.          STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,
  410.          0,0,
  411.          &pStm);        // 取得流接口指针
  412.      assert( SUCCEEDED(hr) );
  413.     }
  414.     void CloseDoc()
  415.     {
  416.      if( pStm )    pStm->Release();// 释放流指针
  417.      if( pSub )    pSub->Release();// 释放子存储指针
  418.      if( pStg )    pStg->Release();// 释放根存储指针
  419.     }
  420.     void WriteSample()
  421.     {
  422.      hr = pStm->Write(        // 向流中写入数据
  423.          "Hello",        // 数据地址
  424.          5,        // 字节长度(注意,没有写入字符串结尾的\0)
  425.          NULL);        // 不需要得到实际写入的字节长度
  426.      assert( SUCCEEDED(hr) );
  427.         
  428.      IPersistStreamInitPtr spStream(CLSID_MySingle,NULL,CLSCTX_ALL);
  429.      if(spStream)
  430.      {
  431.          spStream->InitNew();
  432.          spStream->Save(pStm,TRUE);
  433.          spStream.Release();
  434.      }
  435.     }
  436.     void WriteMarshalToDocument()
  437.     {
  438.         IFunPtr ptr(CLSID_Fun,NULL,CLSCTX_ALL);
  439.         assert(ptr);
  440.         CoMarshalInterface(pStm,IID_IFun,ptr,MSHCTX_LOCAL,NULL,MSHLFLAGS_NORMAL);
  441.         ptr.Release();
  442.     }
  443. };

  444. void SampleCreateDoc()
  445. {
  446.     UseStream obj1;
  447.     obj1.WriteMarshalToDocument();
  448. }

  449. void MarshalOleAutomation()
  450. {
  451.     IE2Ptr ptr(CLSID_E2,NULL,CLSCTX_ALL);
  452.     assert(ptr);
  453.     IStream* pStm;
  454.     HRESULT hr = CoMarshalInterThreadInterfaceInStream(IID_IE2,ptr,&pStm);
  455.     assert(SUCCEEDED(hr));
  456.     IE2Ptr pGet;
  457.     hr=CoGetInterfaceAndReleaseStream(pStm,IID_IE2,(LPVOID*)&pGet);
  458.     assert(SUCCEEDED(hr));
  459.     cout<<pGet->Add(44,3)<<endl;//自定义接口+支持oleautomation
  460.     ptr.Release();
  461. }

  462. class WriteMarshalToMemory
  463. {
  464.     static IStream* pStm;
  465. public:
  466.     static DWORD WINAPI f(void*)
  467.     {
  468.      CoInitialize(NULL);
  469.         IE2Ptr pGet;
  470.         HRESULT hr=CoGetInterfaceAndReleaseStream(pStm,IID_IE2,(LPVOID*)&pGet);
  471.         assert(SUCCEEDED(hr));
  472.         cout<<pGet->Add(44,29)<<endl;
  473.      CoUninitialize();
  474.         return 0;
  475.     }
  476.     WriteMarshalToMemory()
  477.     {
  478.         IE2Ptr ptr(CLSID_E2,NULL,CLSCTX_ALL);
  479.         assert(ptr);
  480.         HRESULT hr = CoMarshalInterThreadInterfaceInStream(IID_IE2,ptr,&pStm);
  481.         assert(SUCCEEDED(hr));

  482.         HANDLE hThread=CreateThread(NULL,size_t(),f,NULL,DWORD(),NULL);
  483.         WaitForSingleObject(hThread,INFINITE);
  484.         ptr.Release();
  485.     }
  486. };
  487. IStream* WriteMarshalToMemory::pStm = NULL;

  488. IStream* g_pStm;
  489. DWORD WINAPI tf(void*)
  490. {
  491.      CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
  492.      IMy1Ptr pGet;
  493.      HRESULT hr=CoGetInterfaceAndReleaseStream(g_pStm,IID_IMy1,(LPVOID*)&pGet);
  494.      assert(SUCCEEDED(hr));
  495.      long ret=pGet->Add(44,29);
  496.      cout<<ret<<endl;
  497.      CoUninitialize();
  498.      return 0;
  499. }
  500. void TestMarshal()
  501. {
  502.      CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
  503.      IMy1Ptr ptr(CLSID_My1,NULL,CLSCTX_ALL);
  504.      assert(ptr);
  505.      HRESULT hr = CoMarshalInterThreadInterfaceInStream(IID_IMy1,ptr,&g_pStm);
  506.      assert(SUCCEEDED(hr));
  507.      HANDLE hThread=CreateThread(NULL,0,tf,NULL,0,NULL);
  508.      Sleep(10000);//子线程调用STA主线程创建的com对象,需要用到主线程的消息队列
  509.      MessageBox(0, _T(""), _T(""), 0);//MessageBox显示的时候创建消息队列,点击OK的时候关闭消息队列
  510.      WaitForSingleObject(hThread,INFINITE);
  511.      ptr.Release();
  512.      CoUninitialize();
  513. }

  514. void UseMyStruct()
  515. {
  516.     IE3Ptr ptr(CLSID_E3,NULL,CLSCTX_ALL);
  517.     My obj={2,"xyz"};
  518.     ptr->SetMy(&obj);
  519.     MyStruct ms={1,2};
  520.     ptr->SetMyStruct(&ms);
  521.     ptr->GetMy(&obj);
  522.     cout<<obj.m_i<<obj.m_str<<endl;
  523.     ptr.Release();
  524. }

  525. void UseClassFactory()
  526. {
  527.     IClassFactory *pFactory=nullptr;
  528.     HRESULT hr=CoGetClassObject(CLSID_My1,CLSCTX_ALL,NULL,IID_IClassFactory,(void**)&pFactory);
  529.     IMy1* pMy1=nullptr;
  530.     hr=pFactory->CreateInstance(NULL,IID_IMy1,(void**)&pMy1);
  531.     cout<<pMy1->Add(3,3)<<endl;
  532.     pMy1->Release();
  533.     pFactory->Release();
  534. }
   ClassFactory的用法如下。

点击(此处)折叠或打开

  1. int main(void)
  2. {
  3.     VARIANT var,var2;
  4.     VariantInit(&var);
  5.     VariantInit(&var2);

  6.     V_VT(&var)=VT_I4;
  7.     V_I4(&var)=20;

  8.     VariantChangeType(&var2,&var,VARIANT_NOVALUEPROP,VT_BSTR);
  9.     _tprintf(var2.bstrVal);

  10.     VariantClear(&var);
  11.     VariantClear(&var2);

  12.     CoInitialize(NULL);
  13.     IClassFactory* pf=NULL;
  14.     HRESULT hr=CoGetClassObject(CLSID_Bar,CLSCTX_ALL,NULL,IID_IClassFactory,(void**)&pf);
  15.     IBar* pBar=NULL;
  16.     hr=pf->CreateInstance(NULL,IID_IBar,(void**)&pBar);
  17.     if(pBar)pBar->Release();
  18.     pf->Release();

  19.     IClassFactory2* pf2=NULL;
  20.     hr=CoGetClassObject(CLSID_Bar,CLSCTX_ALL,NULL,IID_IClassFactory2,(void**)&pf2);
  21.     IBar* pBar2=NULL;
  22.     BSTR bstrKey;
  23.     hr=pf2->RequestLicKey(DWORD(),&bstrKey);
  24.     hr=pf2->CreateInstanceLic(NULL,NULL,IID_IBar,bstrKey,(void**)&pBar2);
  25.     if(pBar2)pBar2->Release();
  26.     pf2->Release();
  27.     CoUninitialize();
  28.     return 0;
  29. }
阅读(8389) | 评论(1) | 转发(2) |
给主人留下些什么吧!~~

mengxingxia2015-05-22 10:10:32

Good for Beginner,3Q!