`
zhaohaolin
  • 浏览: 1017671 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

COM组件开发实践(二)【转】

阅读更多

假设需求如下:底层是一个数学运算库 DLL, 中间是 ActiveX 控件(它调用底层的数学运算库 DLL 来完成控制层),界面层在测试时可以是一个 exe 程序,最后发布到 IE 浏览器上测试。

 

数学运算库 DLL 的开发

      新建一个 Win32 DLL 项目,加入一个头文件 MyNum.h, 在其中声明所有的数学函数(为简单起见,本文只考虑加法运算),代码如下:

#ifndef MY_NUM_H
#define  MY_NUM_H
int  __stdcall AddNum( int , int );
#endif

请注意这里的方法声明为 __stdcall ,而 VC++ 默认的是 __cdecl ,由于组件的语言无关性要求调用和被调双方必须在函数调用的约定上一致,因此在后面加载 DLL 并获取此方法时也要求和你的声明一致。

      为了简单起见,加法方法的实现就放倒 DLL 入口点所在文件 , 代码如下:

//  NumDLL.cpp : 定义DLL 应用程序的入口点。
//
#include  " stdafx.h "
#include 
" MyNum.h "

#ifdef _MANAGED
#pragma  managed(push, off)
#endif

int  __stdcall AddNum( int  Num1, int  Num2)
{
    
return  Num1 + Num2;
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    
return  TRUE;
}


#ifdef _MANAGED
#pragma  managed(pop)
#endif

      为了能在其他程序中显示链接此 DLL ,我们为它加入一个 .def 文件,命名为 NumDLL.def ,列出此 DLL 导出的方法名称:

LIBRARY     " NumDLL "
EXPORTS
    AddNum

至此我们的数学运算函数库 DLL 就完成了。

ATL 开发 ActiveX 控件

      开发 ActiveX 控件有两种方式,一是 MFC, 二是 ATL, 而后者是专门用于 COM 组件开发,因此更适合于 ActiveX 。因此这里选择后者,前者的开发示例参考我这篇文章( 用VC++开发 ActiveX 控件完全教程(一) )。

      新建一个 ATL 项目,命名为 ”FuckATL” ,接受默认设置。右键项目名,添加一个 ”ATL 简单对象 ,命名为 CaluNumCtrl 点击下一步进入组件选项设置界面。

      修改类的头文件 CaluNumCtrl.h 如下:

class  ATL_NO_VTABLE CCaluNumCtrl :
    
public  CComObjectRootEx < CComSingleThreadModel > ,
    
public  CComCoClass < CCaluNumCtrl,  & CLSID_CaluNumCtrl > ,
    
public  ISupportErrorInfo,
    
public  IConnectionPointContainerImpl < CCaluNumCtrl > ,
    
public  CProxy_ICaluNumCtrlEvents < CCaluNumCtrl > ,
    
public  IObjectWithSiteImpl < CCaluNumCtrl > ,
    
public  IDispatchImpl < ICaluNumCtrl,  & IID_ICaluNumCtrl,  & LIBID_FuckATLLib,  /* wMajor = */   1 /* wMinor = */   0 >
{
public :
    typedef 
int  (__stdcall * PtrAddNum)( int , int );
    PtrAddNum MyAddNum;
    CCaluNumCtrl()
    
{
        
// 加载数学运算库DLL
        handle  =  ::LoadLibrary(_T( " D:\\dyk\\work\\NumDLL\\debug\\NumDLL.dll " ));
        
if  (handle  ==  NULL) 
        
{
            DWORD e 
=  GetLastError();
            
return ;
        }

        
// 获取加法运算函数指针
        MyAddNum  =  (PtrAddNum)GetProcAddress(handle, " AddNum " );
    }

DECLARE_REGISTRY_RESOURCEID(IDR_CALUNUMCTRL)
BEGIN_COM_MAP(CCaluNumCtrl)
    COM_INTERFACE_ENTRY(ICaluNumCtrl)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(ISupportErrorInfo)
    COM_INTERFACE_ENTRY(IConnectionPointContainer)
    COM_INTERFACE_ENTRY(IObjectWithSite)
END_COM_MAP()

BEGIN_CONNECTION_POINT_MAP(CCaluNumCtrl)
    CONNECTION_POINT_ENTRY(__uuidof(_ICaluNumCtrlEvents))
END_CONNECTION_POINT_MAP()
//  ISupportsErrorInfo
    STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
    DECLARE_PROTECT_FINAL_CONSTRUCT()
    HRESULT FinalConstruct()
    
{
        
return  S_OK;
    }

    
void  FinalRelease()
    
{
    }

// 组件对外放出的加法方法
public :
    STDMETHOD(AddNumbers)(LONG Num1, LONG Num2, LONG
*  ReturnVal);     // 下面是一个NUM属性,也是用于测试,包含了读写设置方法
public :
    STDMETHOD(get_NUM)(SHORT
*  pVal);
public :
    STDMETHOD(put_NUM)(SHORT newVal);
public :
    HMODULE handle;
// 数学函数库模块句柄
}
;

在控件实现文件 CaluNumCtrl.cpp 中,代码如下:

STDMETHODIMP CCaluNumCtrl::AddNumbers(LONG Num1, LONG Num2, LONG *  ReturnVal)
{
    
int  sum  =   this -> MyAddNum(static_cast < int > (Num1),static_cast < int > (Num2));
    
* ReturnVal  =  static_cast < LONG > (sum);
    
return  S_OK;
}


STDMETHODIMP CCaluNumCtrl::get_NUM(SHORT
*  pVal)
{
    
* pVal  =   10 ;
    
return  S_OK;
}


STDMETHODIMP CCaluNumCtrl::put_NUM(SHORT newVal)
{
    
//  TODO: 在此添加实现代码
    
    
return  S_OK;
}

     好了, ActiveX 控件仅仅是简单地调用底层的数学运算库 DLL 来完成运算,下面我们写一个 exe 程序对这个 COM 组件进行测试。

一个控制台测试程序

      建立一个最简单的控制台程序来进行测试,代码如下:

#include  " ..\..\FuckATL\FuckATL\FuckATL.h "
#include 
" ..\..\FuckATL\FuckATL\FuckATL_i.c "
#include 
< iostream >
using    namespace  std;

void  main( void )
{
    
//  Declare and HRESULT and a pointer to the Simple_ATL interface
    HRESULT            hr;
    ICaluNumCtrl 
* IFirstATL  =  NULL;
    
//  Now we will intilize COM
    hr  =  CoInitialize( 0 );
    
//  Use the SUCCEDED macro and see if we can get a pointer to
    
//  the interface
     if (SUCCEEDED(hr))
    
{
        hr 
=  CoCreateInstance( CLSID_CaluNumCtrl, NULL, CLSCTX_INPROC_SERVER,
            IID_ICaluNumCtrl, (
void ** & IFirstATL);
        
//  If we succeeded then call the AddNumbers method, if it failed
        
//  then display an appropriate message to the user.
         if (SUCCEEDED(hr))
        
{
            
long  ReturnValue;
            hr 
=  IFirstATL -> AddNumbers( 5 7 & ReturnValue);
            cout 
<<   " The answer for 5 + 7 is:  "   <<  ReturnValue  <<  endl;
            
short  num; 
            IFirstATL
-> get_NUM( & num);
            cout
<< " num is:  " << num << endl;
            hr 
=  IFirstATL -> Release();
        }

        
else
        
{
            cout 
<<   " CoCreateInstance Failed. "   <<  endl;
        }

    }

    
//  Uninitialize COM
    CoUninitialize();
    system(
" pause " );
}

来到 IE 的世界

      最后我们将此 ActiveX 组件嵌入到 html 页面中,对其进行测试 . 新建一个 html 页面,代码如下:

< HTML >
< HEAD >
< TITLE > New Page </ TITLE >
< script  language ="javascript" >
    
function  doTest()
    
{
        
var  sum  =  FuckATL1.AddNumbers( 3 , 4 );
        alert(sum);
    }

</ script >
</ HEAD >
< BODY >
< OBJECT  ID ="FuckATL1"  CLASSID ="CLSID:7BF3B65F-A800-4604-AE6B-91844EFD5F05" >
</ OBJECT >
< input  type ="button"  value ="测试加法"  id ="btnOK"  onclick ="doTest();" ></ input >
</ BODY >
</ HTML >

     由于暂时先不考虑控件的安全性需要,因此会出现下面的警告信息,不过不要紧,这个问题以后再解决。

测试结果如下:

 

作者:洞庭散人

出处:http://phinecos.cnblogs.com/     

本博客遵从Creative Commons Attribution 3.0 License ,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。

分享到:
评论

相关推荐

    Web前端工程化与组件化开发实践

    在现代Web开发中,"Web前端工程化与组件化开发实践"已经成为提升开发效率和代码质量的重要手段。本文将深入探讨这两个概念,并结合具体的实践案例,解析如何在JavaScript开发中应用它们。 首先,前端工程化是指通过...

    C#组件开发简易教程.

    通过学习这个C#组件开发简易教程,你将能够理解组件的基本概念,掌握组件开发的关键技术和实践,为构建高效、可维护的C#应用程序打下坚实基础。在实际开发过程中,不断实践和优化,将使你成为组件开发的专家。

    MapGIS组件式二次开发

    MapGIS组件式二次开发是GIS(地理信息系统)领域中的一项核心技术,主要针对MapGIS平台进行应用程序的定制和扩展。在MapGIS的组件式二次开发中,开发者可以利用MapGIS提供的各种组件,通过C++或C#等编程语言,构建出...

    Vue项目组件化工程开发实践方案

    Vue项目组件化工程开发实践方案 本文将详细介绍Vue项目组件化工程开发实践方案,涵盖组件库、文档工程和例子工程三个方面。通过引入vde-cli脚手架,可以快速生成组件库工程目录结构,并且可以自动更新文档工程和...

    VC++编写COM组件教程

    **VC++ 编写COM组件教程** COM(Component Object Model)是微软提出的一...以上内容涵盖了创建和使用COM组件的基本知识,通过学习和实践,你可以熟练地利用VC++开发出高效的COM组件,并在不同的应用程序中灵活使用。

    MapGis组件开发手册

    《MapGis组件开发手册》是一本专注于...总的来说,《MapGis组件开发手册》是MapGIS二次开发者的必备参考资料,它涵盖了从理论到实践的全面指导,旨在帮助开发者充分利用MapGIS组件,实现高效、定制化的GIS解决方案。

    asp组件开发指南

    ASP组件开发指南主要涵盖了几大核心知识点,这些知识点对于深入理解和构建高效、可复用的ASP应用程序至关重要。本文将详细阐述这些关键概念。...不断探索和实践,将有助于你在ASP组件开发领域积累深厚的专业技能。

    前端组件化开发实践 -1

    【前端组件化开发实践 -1】 前端开发领域中,组件化是一种重要的开发模式,它能够有效地管理和控制项目复杂性。随着技术的发展,组件化已成为现代前端框架的核心特性,如React和Vue等。美团点评技术团队在实践中也...

    delphi 组件开发 入门必看

    对于想要入门Delphi组件开发的初学者来说,了解并掌握相关知识至关重要。组件是Delphi编程的核心元素,它们是可重用的代码模块,封装了特定的功能,可以在界面上直接拖放,极大地提高了开发效率。 首先,我们需要...

    QT生成COM组件并调用COM组件测试工程.7z

    QT生成COM组件并调用COM组件测试工程是一个涉及Qt框架与...通过这样的项目实践,开发者可以深入理解Qt与COM的集成,提高跨平台和跨语言组件开发的能力。同时,这也是对C++编程、对象接口设计和软件集成能力的一次锻炼。

    office组件二次开发

    对于开发者来说,这些博客可以作为参考资料,帮助他们理解和实践Office组件的二次开发。 最后,"给 枕善居 发邮件.url"可能是一个联系人信息,如果在使用过程中遇到问题或者需要进一步的技术支持,可以联系这个人或...

    Delphi组件开发指南中文版

    《Delphi组件开发指南中文版》是一本专为Delphi开发者设计的详尽教程,旨在帮助读者深入理解和掌握在Delphi环境下进行组件开发的核心技术。Delphi是一款强大的面向对象的集成开发环境(IDE),以其高效的编译器和...

    基于组件开发的组件选择过程

    基于组件开发(Component-Based Development,简称CBD)是一种现代软件工程方法论,其核心思想在于通过重用预先构建的软件组件来构建新的软件系统,以此提高软件开发效率,降低开发成本,提升软件质量。然而,CBD的...

    VC-COM.zip_ATL vs2010_ATL开发com组件_com开发 vs_vs com组件开发

    开发com组件_com开发 vs_vs com组件开发** 在软件开发中,组件(Component)是一种可重用的代码单元,它可以独立于应用程序而存在,并能被多个应用程序共享。COM(Component Object Model)是微软提出的一种组件...

    COM组件的原理及应用

    这些资料对于深入理解COM组件的原理和实际应用有着极大的帮助,可以帮助读者从基础到实践,全面掌握COM组件的开发和使用技巧。 总之,COM组件是Windows编程中的重要组成部分,理解并熟练使用COM组件,可以提升...

    iOS App 组件化开发实践

    二进制化组件的情况下,业务组件编译速度一般低于 10s。 • 分工更为明确,从而提升开发效率。 • 灵活,耦合低。 • 结合 MVVM。非常细致的单元测试,提高代码质量,保证 App 稳定性。体现在测试人 员反馈的 bug ...

    Unreal Engine开发:动作组件开发-1.动作组件概述.docxUnreal Engine开发:动作组件开发-10.多人游戏中的动作组件同步.docxUnreal Engine开发:动作组

    动作组件开发的最佳实践与常见问题解答.docx Unreal Engine开发:动作组件开发_2.动作组件的基础概念.docx Unreal Engine开发:动作组件开发_3.动作组件的类型与功能.docx Unreal Engine开发:动作组

    组件开发教程

    组件开发教程是一个面向初学者的指南,主要涵盖了COM(Component Object Model)技术的各个方面,旨在帮助读者理解并掌握COM组件的开发。COM是微软提出的一种软件组件标准,它允许不同程序之间共享代码和服务,实现...

    iOS App组件化开发实践1

    在iOS应用开发中,组件化是一种重要的架构设计方法,它能有效地提高代码的复用性、可维护性和团队协作效率。本文将探讨iOS App组件化的实践,主要关注以下几个方面: 1. **组件化概念**:组件化是将一个大型的应用...

Global site tag (gtag.js) - Google Analytics