zoukankan      html  css  js  c++  java
  • vc中调用Com组件的方法详解

    转载自:网络,来源未知,如有知晓者请告知我。

    需求:
    1.创建myCom.dll,该COM只有一个组件,两个接口:
       IGetRes--方法Hello(),
       IGetResEx--方法HelloEx()

    2.在工程中导入组件或类型库

     #import "组件所在目录myCom.dll" no_namespace

       #import "类型库所在目录myCom.tlb"
       using namespace MYCOM;



    方法一:

    1    CoInitialize(NULL);
    2    CLSID clsid;
    3    CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
    4    CComPtr<IGetRes> pGetRes;//智能指针
    5    pGetRes.CoCreateInstance(clsid);
    6    pGetRes->Hello();
    7    pGetRes.Release();//小心哦!!请看最后的“注意”
    8    CoUninitialize();

    方法二:

    1    CoInitialize(NULL);
    2    CLSID clsid;
    3    HRESULT     hr=CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
    4    IGetRes *ptr;
    5    hr=CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
    6                  __uuidof(IGetRes),(LPVOID*)&ptr);
    7    ptr->Hello();
    8    CoUninitialize();

    方法三:

     1    CoInitialize(NULL);
     2    HRESULT hr;
     3    CLSID clsid;
     4    hr=CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
     5    IGetRes* ptr;
     6    IGetResEx* ptrEx;
     7    //使用CoCreateClassObject创建一个组件(特别是mutilThreads)的多个对象的
     8      时候,效率更高.
     9    IClassFactory* p_classfactory;
    10    hr=CoGetClassObject(clsid,CLSCTX_INPROC_SERVER,
    11                        NULL,IID_IClassFactory, 
    12                        (LPVOID*)&p_classfactory);
    13    p_classfactory->CreateInstance(NULL,__uuidof(IGetRes),
    14                                           (LPVOID*)&ptr);
    15    p_classfactory->CreateInstance(NULL,__uuidof(IGetResEx),
    16                                           (LPVOID*)&ptrEx);
    17    ptr->Hello();
    18    ptrEx->HelloEx();
    19    CoUninitialize();

    方法四:
    直接从dll中得到DllGetClassObject,接着生成类对象及类实例(这方法可以
    使组件不用在注册表里注册,这是最原始的方法,但这样做没什么意义,至少失去了COM
    对用户的透明性),不推荐使用.

       typedef HRESULT (__stdcall * pfnHello)(REFCLSID,REFIID,void**);
       pfnHello fnHello= NULL;
       HINSTANCE hdllInst = LoadLibrary("组件所在目录myCom.dll");
       fnHello=(pfnHello)GetProcAddress(hdllInst,"DllGetClassObject");
       if (fnHello != 0)
       {
       IClassFactory* pcf = NULL;
       HRESULT hr=(fnHello)(CLSID_GetRes,IID_IClassFactory,(void**)&pcf);
       if (SUCCEEDED(hr) && (pcf != NULL))
       {
       IGetRes* pGetRes = NULL;
       hr = pcf->CreateInstance(NULL, IID_IFoo, (void**)&pGetRes);
       if (SUCCEEDED(hr)   && (pFoo != NULL))
       {
       pGetRes->Hello();
       pGetRes->Release();
       }
       pcf->Release();
       }
       } 
       FreeLibrary(hdllInst);

    方法五:
    通过ClassWizard利用类型库生成包装类,不过前提是com组件的接口必须是派
    生自IDispatch,具体方法:
        调出添加类向导(.NET中),选择类型库中MFC类,打开,选择"文件",选择
    "myCom.dll"或"myCom.tlb",接下来会出来该myCom中的所有接口,选择你想
    生成的接口包装类后,向导会自动生成相应的.h文件.这样你就可以在你的MFC中
    像使用普通类那样使用组件了.(CreateDispatch("myCom.GetRes") 中的参数就是ProgID通过Clsid在注册表中可以查询的到)

    1    CoInitialize(NULL);
    2    CGetRes getRest;
    3    if (getRest.CreateDispatch("myCom.GetRes") != 0)
    4    {
    5    getRest.Hello();
    6    getRest.ReleaseDispatch();
    7    }
    8    CoUninitialize();

    注意:
    COM中的智能指针实际上是重载了->的类,目的是为了简化引用记数,几不需要程序
    员显示的调用AddRef()和Release(),但是为什么我们在Method 1中
    pGetRes.Release(),问题在与,我们的智能指针pGetRes生命周期的结束是在
    CoUninitialize()之后,CoInitialize所开的套间在CoUninitialize()后已经被
    关闭,而pGetRes此时发生析构,导致了程序的崩溃,解决这个问题的另一个方法是

    1    CoInitialize(NULL);
    2    CLSID clsid;
    3    CLSIDFromProgID(OLESTR("myCom.GetRes"),&clsid);
    4    {
    5    CComPtr<IGetRes> pGetRes;//智能指针
    6    pGetRes.CoCreateInstance(clsid);
    7    pGetRes->Hello();
    8    }
    9    CoUninitialize();

    以上就是COM的5中方法,当然具体怎么使用还是在于程序的环境,加以琢磨....

  • 相关阅读:
    array_map()与array_shift()搭配使用 PK array_column()函数
    Educational Codeforces Round 8 D. Magic Numbers
    hdu 1171 Big Event in HDU
    hdu 2844 poj 1742 Coins
    hdu 3591 The trouble of Xiaoqian
    hdu 2079 选课时间
    hdu 2191 珍惜现在,感恩生活 多重背包入门题
    hdu 5429 Geometric Progression 高精度浮点数(java版本)
    【BZOJ】1002: [FJOI2007]轮状病毒 递推+高精度
    hdu::1002 A + B Problem II
  • 原文地址:https://www.cnblogs.com/LessNull/p/2648940.html
Copyright © 2011-2022 走看看