




已阅读5页,还剩15页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
三、纯手工创建一个COM组件1、从建工程到实现注册在这一过程中我们将完成三个步骤创建DLL的入口函数,定义接口文件,实现注册功能11创建一个类型为WIN32DLL工程创建一个名为MATHCOM的WIN32DLL工程。在向导的第二步选择“ASMIPLEDLLPROJECT“选项。当然如果你选择一个空的工程,那你自己完成DLLMAIN定义吧。12定义接口文件生成一个名为MATHCOMIDL的接口文件。并将此文件加入到刚才创建的那个工程里。VIEWSOURCEPRINT01/MATHCOMIDL文件02/MATHCOMIDLIDLSOURCEFORMATHCOMDLL03/04/THISFILEWILLBEPROCESSEDBYTHEMIDLTOOLTO05/PRODUCETHETYPELIBRARYMATHCOMTLBANDMARSHALLINGCODE06IMPORT“OAIDLIDL“07IMPORT“OCIDLIDL“0809UUIDFAEAE6B767BE42A4A3183256781E945A,10HELPSTRING“ISIMPLEMATHINTERFACE“,11OBJECT,12POINTER_DEFAULTUNIQUE1314INTERFACEISIMPLEMATHIUNKNOWN1516HRESULTADDININTNOP1,ININTNOP2,OUT,RETVALINTPRET17HRESULTSUBTRACTININTNOP1,ININTNOP2,OUT,RETVALINTPRET18HRESULTMULTIPLYININTNOP1,ININTNOP2,OUT,RETVALINTPRET19HRESULTDIVIDEININTNOP1,ININTNOP2,OUT,RETVALINTPRET20212223UUID01147C399DA04F7FB525D129745AAD1E,24HELPSTRING“IADVANCEDMATHINTERFACE“,25OBJECT,26POINTER_DEFAULTUNIQUE2728INTERFACEIADVANCEDMATHIUNKNOWN2930HRESULTFACTORIALININTNOP1,OUT,RETVALINTPRET31HRESULTFABONACCIININTNOP1,OUT,RETVALINTPRET323334UUIDCA3B37EAE44A49B897296E9222CAE844,35VERSION10,36HELPSTRING“MATHCOM10TYPELIBRARY“373839404142LIBRARYMATHCOMLIB4344IMPORTLIB“STDOLE32TLB“45IMPORTLIB“STDOLE2TLB“464748UUID3BCFE27EC88D453C8C94F5F7B97E7841,49HELPSTRING“MATHCOMCLASS“5051COCLASSMATHCOM5253DEFAULTINTERFACEISIMPLEMATH54INTERFACEIADVANCEDMATH5556在编译此工程之前请检查PROJECT/SETTING/MIDL中的设置。正确设置如下图图14MIDL的正确设置在正确设置后,如编译无错误,那么将在工程的目录下产生四个文件名作用MATHCOMH接口的头文件,如果想声明或定义接口时使用此文件MATHCOM_IC定义了接口和类对象以及库,只有在要使用到有关与GUID有关的东西时才引入此文件,此文件在整个工程中只能引入一次,否则会有重复定义的错误MATHCOM_PC用于存根与代理DLLDATAC不明13增加注册功能作为COM必须要注册与注销的功能。131增加一个MATHCOMDEF文件DEF文件是模块定义文件(MODULEDEFINITIONFILE)。它允许引出符号被化名为不同的引入符号。VIEWSOURCEPRINT01/MATHCOMDEF文件02MATHCOMDEFDECLARESTHEMODULEPARAMETERS0304LIBRARY“MATHCOMDLL“0506EXPORTS07DLLCANUNLOADNOW1PRIVATE08DLLGETCLASSOBJECT2PRIVATE09DLLREGISTERSERVER3PRIVATE10DLLUNREGISTERSERVER4PRIVATEDLLUNREGISTERSERVER这是函数名称4这是函数序号PRIVATE接下来大致介绍一下DLLREGISTERSERVER()和DLLUNREGISTERSERVER。(其他两个函数的作用将在后面介绍)132DLLREGISTERSERVER和DLLUNREGISTERSERVERDLLREGISTERSERVER函数的作用是将COM服务器注册到本机上。DLLUNREGISTERSERVER函数的作用是将COM服务器从本机注销。14MATHCOMCPP文件现在请将MATHCOMCPP文件修改成如下VIEWSOURCEPRINT01/MATHCOMCPPDEFINESTHEENTRYPOINTFORTHEDLLAPPLICATION02/03INCLUDE“STDAFXH“04INCLUDE05INCLUDE06INCLUDE“MATHCOMH“07/STANDARDSELFREGISTRATIONTABLE08CONSTCHARG_REGTABLE309“CLSID3BCFE27EC88D453C8C94F5F7B97E7841“,0,“MATHCOM“,10“CLSID3BCFE27EC88D453C8C94F5F7B97E7841INPROCSERVER32“,110,12CONSTCHAR1/表示文件名的值/,13“CLSID3BCFE27EC88D453C8C94F5F7B97E7841PROGID“,0,“TULIPMATHCOM1“,14“TULIPMATHCOM1“,0,“MATHCOM“,15“TULIPMATHCOM1CLSID“,0,“3BCFE27EC88D453C8C94F5F7B97E7841“,1617HINSTANCEG_HINSTDLL18BOOLAPIENTRYDLLMAINHANDLEHMODULE,19DWORDUL_REASON_FOR_CALL,20LPVOIDLPRESERVED212223G_HINSTDLLHINSTANCEHMODULE24RETURNTRUE2526/27FUNCTIONDECLAREDLLUNREGISTERSERVER28EXPLAINSELFUNREGISTRATIONROUTINE29PARAMETERS30VOID31RETURN32STDAPI33AUTHORTULIP34TIME2003102919074235/36STDAPIDLLREGISTERSERVERVOID3738HRESULTHRS_OK39CHARSZFILENAMEMAX_PATH40GETMODULEFILENAMEG_HINSTDLL,SZFILENAME,MAX_PATH4142INTNENTRIESSIZEOFG_REGTABLE/SIZEOFG_REGTABLE43FORINTI0SUCCEEDEDHR12ELSEIFRIIDIID_IADVANCEDMATH13PPVSTATIC_CASTTHIS14ELSEIFRIIDIID_IUNKNOWN15PPVSTATIC_CASTTHIS16ELSE17PPV018RETURNE_NOINTERFACE192021REINTERPRET_CASTPPVADDREF/这里要这样是因为引用计数是针对组件的22RETURNS_OK232425STDMETHODIMP_ULONGCMATHADDREF2627RETURNM_CREF282930STDMETHODIMP_ULONGCMATHRELEASE3132ULONGRESM_CREF/使用临时变量把修改后的引用计数值缓存起来33IFRES0/因为在对象已经销毁后再引用这个对象的数据将是非法的34DELETETHIS35RETURNRES363738STDMETHODIMPCMATHADDINTNOP1,INTNOP2,INTPRET3940PRETNOP1NOP241RETURNS_OK424344STDMETHODIMPCMATHSUBTRACTINTNOP1,INTNOP2,INTPRET4546PRETNOP1NOP247RETURNS_OK484950STDMETHODIMPCMATHMULTIPLYINTNOP1,INTNOP2,INTPRET5152PRETNOP1NOP253RETURNS_OK545556STDMETHODIMPCMATHDIVIDEINTNOP1,INTNOP2,INTPRET5758PRETNOP1/NOP259RETURNS_OK606162INTCMATHCALCFACTORIALINTNOP6364IFNOPQUERYINTERFACERIID,PPV1819RETURNCLASS_E_CLASSNOTAVAILABLE2024客户端接下来我们写个客户端程序对此COM进行测试。新建一个空的名为TESTMATHCOM的WIN32CONSOLE工程,将它添加到MATHCOMWORKSPACE中。在TESTMATHCOM工程里添加一个名为MAINCPP的文件,此文件的内容如下VIEWSOURCEPRINT01/MAINCPP文件02INCLUDE03INCLUDE“/MATHCOMH“/这里请注意路径04INCLUDE“/MATHCOM_IC“/这里请注意路径05INCLUDE06USINGNAMESPACESTD0708VOIDMAINVOID0910/初始化COM库11HRESULTHRCOINITIALIZE012ISIMPLEMATHPSIMPLEMATHNULL13IADVANCEDMATHPADVANCEDMATHNULL1415INTNRETURNVALUE01617HRCOGETCLASSOBJECTCLSID_MATHCOM,18CLSCTX_INPROC,19NULL,IID_ISIMPLEMATH,20VOID21IFSUCCEEDEDHR2223HRPSIMPLEMATHADD10,4,24IFSUCCEEDEDHR25COUTQUERYINTERFACEIID_IADVANCEDMATH,VOID28IFSUCCEEDEDHR2930HRPADVANCEDMATHFABONACCI10,31IFSUCCEEDEDHR32COUTRELEASE35PSIMPLEMATHRELEASE3637COUNINITIALIZE3839SYSTEM“PAUSE“40RETURN4142关于如何调试DLL请参阅附录A25小结到现在我们应该有2个工程和8个文件,具体如下工程文件作用MATHCOMSTDAFXH和STDAFXCPP预编译文件MATHCOMCPPDLL入口函数及其他重要函数定义的地方MATHCOMDEF模块定义文件MATHCOMIDL接口定义文件(在12后如果编译的话应该还有四个文件)MATHH和MATHCPPISMIPLEMATH,IADVANCEDMATH接口的实现类TESTMATHCOMMAINCPPMATHCOM的客户端,用于测试MATHCOM组件在此部分中我们已经完成一个可以实用的接近于完整的COM组件。我们完成了此COM组件的客户端。如果你已经创建COM实例的话,你可能会发现在此部分的客户端并不是用COCREATEINSTANCE来创建COM实例,那是因为我们还没有在此COM组件里实现ICLASSFACTORY接口(此接口在下一部分实现)。通过这个例子,我希望大家明白以下几点1DLLGETCLASSOBJECT()的作用,请参看COM组件调入大致过程这一节,同时也请将断点打在DLLGETCLASSOBJECT函数上,仔细看看他的实现(在没有实现ICLASSFACTORY接口的情况下)和他的传入参数。2为什么在这个客户端程序里不使用COCREATEINSTANCE来创建COM实例而使用COGETCLASSOBJECT来创建COM实例。你可以试着用COCREATEINSTANCE来创建CMATH,看看DLLGETCLASSOBJECT的第一参数是什么3实现ICLASSFACTORY接口不是必需的,但应该说是必要的(如何实现请看下一章)4应掌握DLLREGISTERSERVER和DLLUNREGISTERSERVER的实现。5客户端在调用COM组件时需要那几个文件(只要由IDL文件产生的两个文件)3、类厂附录A我对DLL的一点认识目标写几个比较简单的DLL并了解DLL与LIB的关系。一没有LIB的DLL11建一个没有LIB的DLL1)新建一个COM_1CPP文件(注意此DLL根本没有什么用)2)在COM_1CPP写下下面的代码3)按下F5运行,所有的东西都按确定。4)应该出现如下错误VIEWSOURCEPRINT1LINKING2CREATINGLIBRARYDEBUG/COM_1LIBANDOBJECTDEBUG/COM_1EXP3LIBCDLIBCRT0OBJERRORLNK2001UNRESOLVEDEXTERNALSYMBOL_MAIN4DEBUG/COM_1EXEFATALERRORLNK11201UNRESOLVEDEXTERNALS5进入PROJECT|SETTING,在“C/C“属性框的“PROJECTOPTIONS“里把“/D_CONSOLE“修改成“/D_WINDOWS“。6进入PROJECT|SETTING,在“LINK“属性框的“PROJECTOPTIONS“里增加下面的编译开关“/DLL“增加的编译开关大致如下VIEWSOURCEPRINT1KERNEL32LIBUSER32LIBGDI32LIBWINSPOOLLIB2COMDLG32LIBADVAPI32LIBSHELL32LIB3OLE32LIBOLEAUT32LIBUUIDLIBODBC32LIB4ODBCCP32LIB/NOLOGO/DLL/INCREMENTALYES5/PDB“DEBUG/COM_1PDB“/DEBUG/MACHINEI386/OUT“6DEBUG/COM_1DLL“/IMPLIB“DEBUG/COM_1LIB“7/PDBTYPESEPT注意“/DLL“应该与后面的开关之间有一个空格VIEWSOURCEPRINT01/COM_1CPP02INCLUDE03BOOLAPIENTRYDLLMAINHANDLEHMODULE,DWORDDWREASON,VOIDLPRESERVED0405HANDLEG_HMODULE06SWITCHDWREASON0708CASEDLL_PROCESS_ATTACH09G_HMODULEHINSTANCEHMODULE10BREAK11CASEDLL_PROCESS_DETACH12G_HMODULENULL13BREAK1415现在可以编译了,这小片段代码将会生成一个DLL,但这个DLL是没有用的。没有引出函数和变量。12调试没有LIB的DLL1新建一个工程CLIENT,工程类型为CONSOLE,将上面创建的DLLCOPY到CLIENT工程目录下2增加CLIENTCPP(代码见下)到工程CLIENT中去3选中CLIENT工程,并在PROJECT|SETTING|DEBUG|CATEGORY下拉框,如图图14调试注意这是一种调试DLL的方法5)现在可以在CLIENT和COM_1DLL里打断点调试了。在这里我们只能调试DLLMAIN函数,因为那个DLL里除了就没别的东西了,下面我开始增加一点东西。二带有LIB的DLL21创建一个带有LIB的DLL我们在原来的基础上让上面的代码产生一个LIB了。新的代码如下VIEWSOURCEPRINT01INCLUDE0203EXTERN“C“_DECLSPECDLLEXPORTVOIDTULIPVOID0405MESSAGEBOXNULL,“OK“,“IAMFINE“,MB_OK060708BOOLAPIENTRYDLLMAINHANDLEHMODULE,DWORDDWREASON,VOIDLPRESERVED0910HANDLEG_HMODULE11SWITCHDWREASON1213CASEDLL_PROCESS_ATTACH14G_HMODULEHINSTANCEHMODULE15BREAK16CASEDLL_PROCESS_DETACH17G_HMODULENULL18BREAK192021RETURNTRUE22在这个DLL里,我们引出一个TULIP函数。如果此时我们想要在客户调用此函数应该用什么方法呢上面的代码除了生成DLL外,他比第一个程序多产生一个LIB文件,现在应该知道DLL与LIB的关系吧。LIB文件是DLL输出符号文件。如果一个DLL没有任何东西输出那么不会有对应的LIB文件,但只要一个DLL输出一个变量或函数就会相应的LIB文件。总的说来,DLL与LIB是相互配套的。当某个DLL他有输出函数(或变量)而没有LIB文件时,我们应该怎么调用DLL的函数呢请看下面的方法。22调试带有引用但没有头文件的DLL注意本方法根本没有用COM_1LIB文件,你可以把COM_1LIB文件删除而不影响。此时的客户端代码如果下VIEWSOURCEPRINT01INCLUDE0203INTMAINVOID0405/定义一个函数指针06TYPEDEFVOIDTULIPFUNCVOID0708/定义一个函数指针变量09TULIPFUNCTULIPFUNC1011/加载我们的DLL12HINSTANCEHINSTLOADLIBRARY“COM_1DLL“1314/找到DLL的TULIP函数15TULIPFUNCTULIPFUNCGETPROCADDRESSHINST,“TULIP“1617/调用DLL里的函数18TULIPFUNC1920RETURN021对于调用系统函数用上面的方法非常方便,因为对于USER32DLL,GUI32DLL这种DLL,我没有对应的LIB,所以一般用上面的方法。三带有头文件的DLL31创建一个带有引出信息头文件的DLL如果用上面的方法调用我们自己创建的DLL那太烦了因为我们的DLL可能没有像WINDOW这样标准化的文档。可能过了一段时间后,我们都会忘记DLL内部函数的格式。再如当我们把此DLL发布客户时,那个客户肯定会在背后骂你的这时我们需要一个能了解DLL引出信息途径。我创
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 广播电视与通信课件
- 安全培训效益评估方案课件
- 2025年浙江杭州市萧山区第三人民医院招聘编外人员1人考前自测高频考点模拟试题及答案详解(有一套)
- Hydroxyethyl-starch-Mw-110-150-kDa-生命科学试剂-MCE
- 2025年精密箱体系统项目合作计划书
- hCA-I-hCA-II-IN-1-生命科学试剂-MCE
- 2025年重水堆核电站及配套产品项目发展计划
- 2025广西来宾盛亿土地整治开发有限公司招聘拟聘人员模拟试卷及答案详解(历年真题)
- 2025年延安通和电业有限责任公司招聘(5人)模拟试卷及答案详解(夺冠)
- 技术方案编制与评审工具
- 《情满今生》读书笔记模板
- 胸痛中心网络医院STEMI患者绕行急诊和CCU方案流程图
- 2021年一级注册消防工程师继续教育试题答案
- 急危重病人营养与代谢支持
- 甲醇理化性质及危险特性表MSDS
- GB/T 7216-2009灰铸铁金相检验
- GB/T 5796.3-1986梯形螺纹基本尺寸
- 华北理工大学2016年《互换性及技术测量》期末考试复习题
- 医学影像学总论-X线课件
- 大班科学《神奇的洞洞》课件
- 第二次全国陆生野生动物资源调查技术规程
评论
0/150
提交评论