`
阿尔萨斯
  • 浏览: 4180682 次
社区版块
存档分类
最新评论

MFC DLL向导(二)

 
阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>

使用DLL的一个比较严重的问题就是编译器之间的兼容性问题。不同的编译器对c++函数在二进制级别的实现方式是不同的。所以对基于C++的DLL,如果编译器不同就有很麻烦的。如果创建的是MFC扩展DLL,就不会存在问题,因为它只能被动态连接到MFC的客户应用程序。这里不是本文讨论的重点。

一、重新编译问题
我们先来看一个在实际中可能遇到的问题:
比如现在建立好了一个DLL导出了CMyClass类,客户也能正常使用这个DLL,假设CMyClass对象的大小为30字节。如果我们需要修改DLL中的CMyClass类,让它有相同的函数和成员变量,但是给增加了一个私有的成员变量int类型,现在CMyClass对象的大小就是34字节了。当直接把这个新的DLL给客户使用替换掉原来30字节大小的DLL,客户应用程序期望的是30字节大小的对象,而现在却变成了一个34字节大小的对象,糟糕,客户程序出错了。
类似的问题,如果不是导出CMyClass类,而在导出的函数中使用了CMyClass,改变对象的大小仍然会有问题的。这个时候修改这个问题的唯一办法就是替换客户程序中的CMyClass的头文件,全部重新编译整个应用程序,让客户程序使用大小为34字节的对象。
这就是一个严重的问题,有的时候如果没有客户程序的源代码,那么我们就不能使用这个新的DLL了。

二、解决方法
为了能避免重新编译客户程序,这里介绍两个方法:(1)使用接口类。(2)使用创建和销毁类的静态函数。
1、使用接口类
接口类的也就是创建第二个类,它作为要导出类的接口,所以在导出类改变时,也不需要重新编译客户程序,因为接口类没有发生变化。
假设导出的CMyClass类有两个函数FunctionA FunctionB。现在创建一个接口类CMyInterface,下面就是在DLL中的CMyInterface类的头文件的代码:
# include "MyClass.h"
class _declspec(dllexport) CMyInterface
{
CMyClass *pmyclass;
CMyInterface();
~CMyInterface();
public:
int FunctionA(int);
int FunctionB(int);
};
而在客户程序中的头文件稍不同,不需要INCLUDE语句,因为客户程序没有它的拷贝。相反,使用一个CMyClass的向前声明,即使没有头文件也能编译:
class _declspec(dllexport) CMyInterface
{
class CMyClass;//向前声明
CMyClass *pmyclass;
CMyInterface();
~CMyInterface();
public:
int FunctionA(int);
int FunctionB(int);
};
在DLL中的CMyInterface的实现如下:
CMyInterface::CMyInterface()
{
pmyclass = new CMyClass();
}
CMyInterface::~CMyInterface()
{
delete pmyclass;
}
int CMyInterface::FunctionA()
{
return pmyclass->FunctionA();
}
int CMyInterface::FunctionB()
{
return pmyclass->FunctionB();
}
.....
对导出类CMyClass的每个成员函数,CMyInterface类都提供自己的对应的函数。客户程序与CMyClass没有联系,这样任意改CMyClass也不会有问题,因为CMyInterface类的大小没有发生变化。即使为了能访问CMyClass中的新增变量而给CMyInterface类加了函数也不会有问题的。
但是这种方法也存在明显的问题,对导出类的每个函数和成员变量都要对应实现,有的时候这个接口类会很庞大。同时增加了客户程序调用所需要的时间。增加了程序的开销。

2、使用静态函数
还可以使用静态函数来创建和销毁类对象。创建一个导出类的时候,增加两个静态的公有函数CreateMe()/DestroyMe(),头文件如下:
class _declspec(dllexport) CMyClass
{
CMyClass();
~CMyClass();
public:
static CMyClass *CreateMe();
static void DestroyMe(CMyClass *ptr);
};
实现函数就是:
CMyClass * CMyClass::CMyClass()
{
return new CMyClass;
}
void CMyClass::DestroyMe(CMyClass *ptr)
{
delete ptr;
}
然后象其他类一样导出CMyClass类,这个时候在客户程序中使用这个类的方法稍有不同了。如若想创建一个CMyClass对象,就应该是:
CMyClass x;
CMyClass *ptr = CMyClass::CreateMe();
在使用完后删除:
CMyClass::DestroyMe(ptr);




分享到:
评论

相关推荐

    MFC 手动添加消息

    mfc中,手把手教您怎么自己在处程序中添加自己自定义的消息。

    dll.rar_mfc appwizard dll

    用两个向导(MFC AppWizard(DLL) 和Win32 Dynamic-Link Library)编写一个含有一个计算两个输入参数平均值函数接口的动态链接库。 要求算法正确。 要求在屏幕上输入数字,并显示输出结果。 使用显示链接和隐式链接的...

    vc.rar_9-12 VC_MFC与网络通信_mfc activex_vc dll_vc 生成 dll 文件

    第9课 如何修改MFC AppWizard向导生成的框架程序的外观和大小 24 第10课 图形的绘制,如何使用自定义画笔 27 第11课 如何让CDC上输出的文字、图形具有保持功能 29 第12课 文件操作 31 第13课 使用CArchive类对文件...

    SingDocRglDll_dll中封装MFC_Vc_

    在动态连接库内封装应用程序框架VC源代码,用MFC的程序向导生成一个常规DLL

    在动态连接库内封装应用程序框架cool.zip_ CWinThread_CMainFrame_dll_动态连接库 _资源 DLL

    实现方法: 用MFC的程序向导生成一个常规DLL,在常规DLL内有一派生自CWinApp的实例,再用MFC的程序向导生成一个MFC EXE应用程序,把MFC EXE应用程序中 CAppView,CMainFrame,CAppDocument的文挡和RES目录下的资源拷贝到...

    深入解析MFC

    本书的第一部分包含了核心的MFC图形用户界面类以及支持它们的类,第二部分包含了像OLE这种扩展基本Windows支持的主题。如果做到以下几点,你就可以成为一位透彻理解MFC实现细节的专家:探索MFC文档/视图结构的内幕,...

    DLL调用OCX的例子demo

    OCX做好之后, 通过ClassWizard利用类型库生成包装类,生成的接口包装类后,向导会自动生成相应的.h文件.这样你就可以在你的MFC中像使用普通类那样使用组件了, 在DLL里面, 通过BOOL bRet = m_lpOCX-&gt;CreateDispatch...

    MFC技术内幕

    利用MFC开发Windows程序已成为编程的主流。本书引导读者逐渐深入了解MFC,并向读者展示如何避免走弯路,以及如何创建非同寻常的程序。本书还包括某些MFC的高级特性,如多线程、数据库、扩展DLL和自定义向导。

    VC++动态链接库(DLL)编程

    关于VC++向导、MFC DLL、静态、动态开发DLL的一本好书,详细的介绍了关于基于动态链接库的开发与应用。注入与HOOK

    如何用VC++创建及调用DLL

    // SampleDLL.def // LIBRARY "sampleDLL" EXPORTS HelloWorld示例 DLL 和应用程序XXXXXXXX 在 Microsoft Visual C++ 6.0 中,可以通过选择“Win32 动态链接库”项目类型或“MFC 应用程序向导 (dll)”来创建 DLL。...

    MFC界面美化皮肤

    • 将SkinMagicTrial.lib、SkinMagicTrial.dll和SkinMagicLib.h拷贝到项目根目录下,并在工程中添加; • 把Skins文件夹放在项目根目录下; • 建立一个MFC单文档项目; • 将 #include "SkinMagicLib.h" 拷贝到 ...

    Visual C++2010开发权威指南.part05

    11.3 MFC ActiveX控件向导 458 11.4 ActiveX控件属性开发 458 11.4.1 添加常用属性 459 11.4.2 添加自定义属性 460 11.4.3 高级属性实现 460 11.4.4 访问环境属性 461 11.5 ActiveX控件事件开发 461 11.5.1 添加常用...

    用VS2010生成OCX控件.zip

    新建项目,选择 MFC DLL 这里随便选,我选择共享 MFC DLL 添加类 添加一个 ATL 简单对象 下一步,下一步,完成 实现接口:IObjectSafetyImpl public IObjectSafetyImpl,INTERFACESAFE_FOR_UNTRUSTED_CALLER|...

    MFC串口通信

    // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, //则需要 InitCommonControlsEx()。 否则,将无法创建窗口。 INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // 将它设置...

    标准MFC WinSock ActiveX控件开发实例

    重载控件消息处理函数WindowProc(),在View-&gt;ClassWizard中打开类向导,在消息映射中找到WindowProc,如下图: 图五 重载WindowProc() 四、编写代码 编写VariantToLong()转换函数,该函数代码如下: //类型转换,将...

    基于·MFC的异步slave fifo的CYUSB3014的USB3.0上位机

    如果应用程序使用共享 DLL 中的 MFC,您将需要重新分发 MFC DLL。如果应用程序所使用的语言与操作系统的区域设置不同,则还需要重新分发相应的本地化资源 mfc110XXX.DLL。 有关上述话题的更多信息,请参见 MSDN 文档...

    在动态连接库内封装应用程序框架VC源代码

    实现方法:用MFC的程序向导生成一个常规DLL,在常规DLL内有一派生自CWinApp的实例,再用MFC的程序向导生成一个MFCEXE应用程序,把MFC EXE应用程序中CAppView,CMainFrame,CAppDocument的文挡和RES目录下的资源拷贝到常规...

    人脸相似度检测

    如果应用程序在共享的 DLL 中使用 MFC,则需要重新发布这些 MFC DLL;如果应用程序所用的语言与操作系统的当前区域设置不同,则还需要重新发布对应的本地化资源 MFC90XXX.DLL。有关这两个主题的更多信息,请参见 ...

    接口/总线/驱动中的基于UG的接口技术研究

    摘要:探讨了UG二次开发中的接口技术,通过直接在MFC应用向导程序中加入UG入口函数的方法,解决了利用MenuScript菜单和UIStyler的回调函数无法直接调用MFC函数的问题。给出了访问数据库的实现方案,实现了DLL接ISI与...

Global site tag (gtag.js) - Google Analytics