创建一个COM组件

这篇博客详细介绍了如何创建一个COM组件,包括从创建Win32 DLL工程、定义接口文件、实现注册功能,到实现ISmipleMath和IAdvancedMath接口、DllGetClassObject(),最后实现IDispatch接口以支持脚本环境。通过修改MathCOM.idl、math.h和math.cpp文件,使组件支持双接口,并提供了IDispatch接口的Invoke方法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

1、从建工程到实现注册

在这一过程中我们将完成三个步骤:创建dll的入口函数,定义接口文件,实现注册功能

1.1创建一个类型为win32 dll工程

创建一个名为MathCOM的win32 dll工程。

在向导的第二步选择"A smiple dll project"选项。当然如果你选择一个空的工程,那你自己完成DllMain定义吧。

1.2定义接口文件

生成一个名为MathCOM.idl的接口文件。并将此文件加入到刚才创建的那个工程里。

// MathCOM.idl : IDL source for MathCOM.dll

//

// This file will be processed by the MIDL tool to

// produce the type library (MathCOM.tlb) and marshalling code.

 

import"oaidl.idl";

import"ocidl.idl";

     [

         uuid(FAEAE6B7-67BE-42a4-A318-3256781E945A),

         helpstring("ISimpleMath Interface"),

         object,

         pointer_default(unique)

     ]

     interfaceISimpleMath : IUnknown

     {

         HRESULTAdd([in]intnOp1,[in]intnOp2,[out,retval]int *pret);

         HRESULTSubtract([in]intnOp1,[in]intnOp2,[out,retval]int *pret);

         HRESULTMultiply([in]intnOp1,[in]intnOp2,[out,retval]int * pret);

         HRESULTDivide([in]intnOp1,[in]intnOp2,[out,retval]int *pret);

     };

 

     [

         uuid(01147C39-9DA0-4f7f-B525-D129745AAD1E),

         helpstring("IAdvancedMath Interface"),

         object,

         pointer_default(unique)

     ]

     interfaceIAdvancedMath : IUnknown

     {

         HRESULTFactorial([in]intnOp1,[out,retval]int *pret);

         HRESULTFabonacci([in]intnOp1,[out,retval]int *pret);

     };

[

     uuid(CA3B37EA-E44A-49b8-9729-6E9222CAE844),

     version(1.0),

     helpstring("MATHCOM 1.0 Type Library")

]

libraryMATHCOMLib

{

     importlib("stdole32.tlb");

     importlib("stdole2.tlb");

 

 

     [

         uuid(3BCFE27E-C88D-453C-8C94-F5F7B97E7841),

         helpstring("MATHCOM Class")

     ]

     coclassMATHCOM

     {

         [default]interface ISimpleMath;

         interfaceIAdvancedMath;

     };

};

 在编译此工程之前请检查Project/Setting/MIDL中的设置。正确设置如下图:

图1.4 midl的正确设置

在正确设置后,如编译无错误,那么将在工程的目录下产生四个 

文件名

作用

MathCOM.h

接口的头文件,如果想声明或定义接口时使用此文件

MathCOM_i.c

定义了接口和类对象以及库,只有在要使用到有关与GUID有关的东西时才引入此文件,此文件在整个工程中只能引入一次,否则会有重复定义的错误

MathCOM_p.c

用于存根与代理

dlldata.c

不明

1.3增加注册功能

作为COM必须要注册与注销的功能。

1.3.1增加一个MathCOM.def文件

DEF文件是模块定义文件(Module Definition File)。它允许引出符号被化名为不同的引入符号。

; MathCOM.def : Declares the module parameters.

 

LIBRARY      "MathCOM.DLL"

 

EXPORTS

     DllCanUnloadNow     @1 PRIVATE

     DllGetClassObject   @2 PRIVATE

     DllRegisterServer   @3 PRIVATE

     DllUnregisterServer    @4 PRIVATE

DllUnregisterServer 这是函数名称 @4<――这是函数序号 PRIVATE

接下来大致介绍一下DllRegisterServer()和DllUnregisterServer()。(其他两个函数的作用将在后面介绍)

1.3.2 DllRegisterServer()DllUnregisterServer()

DllRegisterServer() 函数的作用是将COM服务器注册到本机上。

DllUnregisterServer() 函数的作用是将COM服务器从本机注销。

1.4 MathCOM.cpp文件

现在请将 MathCOM.cpp 文件修改成如下:

// MATHCOM.cpp : Defines the entry point for the DLL application.

//

 

#include"stdafx.h"

#include<objbase.h>

#include<initguid.h>

#include"MathCOM.h"

 

#include"math.h"

#include"MathCOM_i.c"

 

 

 

//standard self-registration table

constchar * g_RegTable[][3]={

     { "CLSID\\{3BCFE27E-C88D-453C-8C94-F5F7B97E7841}",0,"MathCOM"},

     { "CLSID\\{3BCFE27E-C88D-453C-8C94-F5F7B97E7841}\\InprocServer32",0,(constchar * )-1 /*表示文件名的值*/},

     { "CLSID\\{3BCFE27E-C88D-453C-8C94-F5F7B97E7841}\\ProgID",0,"tulip.MathCOM.1"},

     { "tulip.MathCOM.1",0,"MathCOM"},

     { "tulip.MathCOM.1\\CLSID",0,"{3BCFE27E-C88D-453C-8C94-F5F7B97E7841}"},

};

 

HINSTANCE g_hinstDll;

 

BOOLAPIENTRY DllMain(HANDLE hModule,

                       DWORD ul_reason_for_call,

                       LPVOIDlpReserved

                        )

{

     g_hinstDll=(HINSTANCE)hModule;

    returnTRUE;

}

 

/*********************************************************************

 * Function Declare : DllUnregisterServer

 * Explain : self-unregistration routine

 * Parameters :

 * void --

 * Return :

 * STDAPI  --

 * Author : tulip

 * Time : 2003-10-29 19:07:42

*********************************************************************/

STDAPIDllUnregisterServer(void)

{

     HRESULThr=S_OK;

     charszFileName [MAX_PATH];

     ::GetModuleFileName(g_hinstDll,szFileName,MAX_PATH);

 

     intnEntries=sizeof(g_RegTable)/sizeof(*g_RegTable);

     for(inti =0;SUCCEEDED(hr)&&i<nEntries;i++)

     {

         constchar * pszKeyName=g_RegTable[i][0];

         longerr=::RegDeleteKey(HKEY_CLASSES_ROOT,pszKeyName);

         if(err!=ERROR_SUCCESS)

              hr=S_FALSE;

     }

 

     returnhr;

}

 

/*********************************************************************

 * Function Declare : DllRegisterServer

 * Explain : self Registration routine

 * Parameters :

 * void --

 * Return :

 * STDAPI  --

 * Author : tulip

 * Time : 2003-10-29 19:43:51

*********************************************************************/

STDAPIDllRegisterServer(void)

{

     HRESULThr=S_OK;

     charszFileName [MAX_PATH];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值