zoukankan      html  css  js  c++  java
  • 最原始的COM组件调用过程(不使用注册表信息)

    最原始的COM组件调用过程(不使用注册表信息)

    最近因为项目的关系开始研究COM组件了,以前都认为COM过时了,所以也没怎么接触. 现在好好补补课了.

    一般调用COM都是通过注册表找到它的位置, 然后调用COM库的标准函数. 这些封装无疑使得我这个初学者无法了解里面到底做了什么, 而且注册表和COM库标准函数都是windows提供的, 但是COM这个思想是可以在Linux下实现的. 只要知道它的实现原理就行了. 因此我就试着用最基本的调用方法来使用COM组件, 以了解其调用过程和原理.

    首先,我用vs的ATL创建了一个简单的ATL项目test, 然后添加了一个简单对象Mytest, 该对象实现了一个IMytest接口,该接口有一个testfunc函数. 编译生成了一堆自动产生的文件, 我们只需要最后的test.dll文件和test.h文件. 有了这两个文件,我们就可以使用该组件中实现的接口了.

    然后,我创建了一个win32控制台项目来测试一下如何不使用注册表来调用COM组件中的接口方法. 不使用注册表,那么该test.DLL文件也就不需要使用regsvr32.exe来注册组件了,我们使用手动加载的方式来使用COM组件. (将test.dll放在win32程序运行目录下,将test.H文件放在win32工程目录下)

    过程如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    // usetest.cpp : 定义控制台应用程序的入口点。
    //
    #include "stdafx.h"
    #include "test.h"
    //#import "test.dll"
    #include <iostream>
    using namespace std;
    typedef HRESULT ( __stdcall *CREATEFUNC)(REFCLSID clsid,REFIID iid,void** ppobj);
    int _tmain(int argc, _TCHAR* argv[])
    {
    HINSTANCE hi= ::LoadLibrary(L"test.dll");
    if(hi!=NULL)
    {
       cout<<"dll loaded."<<endl;
       CREATEFUNC CreateInstance = (CREATEFUNC)::GetProcAddress(hi,"DllGetClassObject");
       if(CreateInstance!=NULL)
       {
        cout<<"get DllGetClassObject method - Success."<<endl;
        IClassFactory* pICF = NULL;
        HRESULT hr = CreateInstance(__uuidof(Mytest),IID_IClassFactory,(void**)&pICF);
        if(SUCCEEDED(hr))
        {
         cout<<"create IClassFactory - Success."<<endl;
         IMytest* pIMytest=NULL;
         HRESULT hr2 = pICF->CreateInstance(NULL,__uuidof(IMytest),(void**)&pIMytest);
         if (SUCCEEDED(hr2))
         {
          cout<<"get interface - Success."<<endl;
          HRESULT hr3=pIMytest->testfunc(1);
          if (SUCCEEDED(hr3))
          {
           cout<<"Invoke interface method OK."<<endl;
          }
          pIMytest->Release();
         }
         pICF->Release();
        }
       }
       FreeLibrary(hi);
    }
    return 0;
    }

    和windows相关的只用到了dll加载相关的API,而这些在其他系统下都有对应的api. 所以如果想在其他系统下实现以下COM的调用, 还是可以的.

    更进一步,可以使用xml文件来维护com组件的位置信息, 然后写一套与系统无关的通过xml文件查找com组件的库,这样就可以实现com组件的跨平台了.

    哈哈,想法不错,实现起来还是有难度的.

  • 相关阅读:
    poj2976 Dropping tests (01分数规划)
    bzoj5281/luogu4377 Talent Show (01分数规划+背包dp)
    bzoj5280/luogu4376 MilkingOrder (二分答案+拓扑序)
    bzoj1492/luogu4027 货币兑换 (斜率优化+cdq分治)
    [模板]树状数组
    匿名函数 python
    yield解析你要知道的源自IBM
    stackoverflow yield 帖子
    pandas 生成器,生成大数据
    pd.contact,dataframe 拼接
  • 原文地址:https://www.cnblogs.com/liangxiaofeng/p/3224499.html
Copyright © 2011-2022 走看看