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组件的跨平台了.

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

  • 相关阅读:
    左孩子右兄弟的字典树
    UVA 1401 Remember the Word
    HDOJ 4770 Lights Against Dudely
    UvaLA 3938 "Ray, Pass me the dishes!"
    UVA
    Codeforces 215A A.Sereja and Coat Rack
    Codeforces 215B B.Sereja and Suffixes
    HDU 4788 Hard Disk Drive
    HDU 2095 find your present (2)
    图的连通性问题—学习笔记
  • 原文地址:https://www.cnblogs.com/liangxiaofeng/p/3224499.html
Copyright © 2011-2022 走看看