上海到马来西亚多久:COM组件的调用方式#include

来源:百度文库 编辑:偶看新闻 时间:2024/04/27 15:40:25
假设所开发的组件为Simple16.DLL(项目名也如此),编译后的项目中存在Simple16_i.c、Simple16_i.h、Simple16_tlb文件COM初始化:可以使用AfxOleInit()或[::CoInitialize(NULL)和::CoUninitialize()成对使用]方式1:#include完全用最基本的 API 方式调用组件,使大家熟悉调用原理#include "Simple16_i.h"#include "Simple16_i.c" 使用:IUnknown* pUn = NULL;
 IDispConnect* pDispConnect = NULL;
 HRESULT hr;
 hr = ::CoCreateInstance(CLSID_DispConnect,  // DispConnect,是Simple16项目中的ATL 简单对象
  NULL,
  CLSCTX_INPROC_SERVER,
  IID_IUnknown,
  (LPVOID*)&pUn
  );
 if (SUCCEEDED(hr))
 {
  hr = pUn->QueryInterface(IID_IDispConnect, (LPVOID*)&pDispConnect);
  if (SUCCEEDED(hr))
  {
   hr = pDispConnect->Add(1, 3); // 库中提供的方法,结果通过事件返回的
  }
 } if (pUn)
 {
  pUn->Release();
 } if (pDispConnect)
 {
  pDispConnect->Release();
 }方法二:#include展示智能指针 CComPtr<> 的使用方法

#include "simple16_i.h"
#include "simple16_i.c"

CComPtr < IUnknown > spUnk;  // 定义 IUnknown 智能指针
 CComPtr < IDispConnect > spDispConnect;   // 定义 IDispConnect 智能指针
 HRESULT hr;

 try
 {
  // 可以用 CLSID 启动组件,也可以用 ProgID
  hr = spUnk.CoCreateInstance( CLSID_DispConnect );
  if( FAILED( hr ) ) throw( _T("没有注册组件吧?") );

  hr = spUnk.QueryInterface( &spDispConnect);
  if( FAILED( hr ) ) throw( _T("居然没有接口?") );

  hr = spDispConnect->Add( 1, 2);
  if( SUCCEEDED( hr ) )
  {
  }
 catch( LPCTSTR lpErr )
 {
  AfxMessageBox( lpErr );
 } // 智能接口指针的最大好处是,我们不用负责释放
方法三:#include展示智能指针 CComPtr<> 和 CComQIPtr<> 混合的使用方法

#include "simple16_i.h"
#include "simple16_i.c"

CComPtr < IUnknown > spUnk;  // 定义 IUnknown 智能指针
 CComQIPtr< IDispConnect > spDispConnect;   // 定义 IDispConnect 智能指针
 HRESULT hr;

 try
 {
  // 可以用 CLSID 启动组件,也可以用 ProgID
  hr = spUnk.CoCreateInstance( L"Simple16.DispConnect"); // 使用 ProgID 启动组件
  if( FAILED( hr ) ) throw( _T("没有注册组件吧?") );

  spDispConnect= spUnk; // CComQIPtr 会帮我们自动调用 QueryInterface 
  if( !spDispConnect ) throw( _T("居然没有接口?") );
  hr = spDispConnect->Add( 1, 2);
  if( SUCCEEDED( hr ) )
  {
  }
 catch( LPCTSTR lpErr )
 {
  AfxMessageBox( lpErr );
 }[注意:]ATL 提供了2个智能指针的模板包装类,CComPtr<> 和 CComQIPtr<>,这两个类都在 中声明。CComQIPtr<> 包含了 CComPtr<>的所有功能,因此我们可以完全用 CComQIPtr<> 来使用智能接口指针,唯一要说明的一点就是:CComQIPtr<> 由于使用了运算符的重载功能,它会自动帮我们调用QueryInterface()函数,因此 CComQIPtr<> 唯一的缺点就是不能定义 IUnknown * 指针。
    // 智能指针 smart pointer,按照匈牙利命名法,一般以 sp 开头来表示变量类型    CComPtr < IUnknown > spUnk;// 正确    // 假设 IFun 是一个接口类型    CComPtr < IFun > spFun;// 正确    CComQIPtr < IFun > spFun;// 正确    CComQIPtr < IFun, &IID_IFun > spFun;// 正确    CComQIPtr < IUnknown > spUnk;// 错误!CComQIPtr不能定义IUnknown指针
 
方法四:
#include展示智能指针 CComQIPtr<> 的使用方法以及释放方法

#include "simple16_i.h"
#include "simple16_i.c"

::CoInitialize( NULL );  // 如果在这里进行 COM 初始化,要注意智能指针的释放

 CComQIPtr < IDispConnect , &IID_IDispConnect  > spDispConnect ;

 HRESULT hr = spFun.CoCreateInstance( CLSID_DispConnect  );
 ASSERT( SUCCEEDED( hr ) );
 // 为了简单起见,不再使用 if 判断 HRESULT 了。

 // CComBSTR s1( "Hello" ), s2( " world" ), s3;
 hr = spDispConnect ->Add( 1, s2, &s3 );
 ASSERT( SUCCEEDED( hr ) );
 

// spFun->Release(); // 大错特错!!!
 spFun.Release(); // 正解

 ::CoUninitialize();