导出一个从CView继承的类MapView,新建一个单文档工程,将里面视图类的基类改为MapView类,debug模式下运行出现如下错误(导出MapView类的动态库是Release版本),点击忽略系统可正常运行,将导出MapView类的动态库编译为Debug版本,系统正常运行,debug模式下系统正常运行但是release模式下会出问题。
原来导出动态库的方式如下:
#ifndef _BLUEMAP_MAPVIEW_
#define BLUEMAP_MAPVIEW _declspec(dllimport)
#else
#define BLUEMAP_MAPVIEW _declspec(dllexport)
#endif
class BLUEMAP_MAPVIEW MapView : public CView
{
DECLARE_DYNCREATE(MapView)
…………………………………………….动态库代码段
};
#ifndef _BLUEMAP_MAPVIEW_
#ifdef _DEBUG
#pragma comment(lib, "MapView.lib")
#pragma message("debug模式下自动链接MapView.lib")
#else
#pragma comment(lib, "MapView.lib")
#pragma message("非debug模式下自动链接MapView.lib")
#endif
#endif
解决方案:
第一步:将MapView在Debug和Release模式下以不同的动态库方式导出
动态库头文件如下:
#ifndef _BLUEMAP_MAPVIEW_
#define BLUEMAP_MAPVIEW _declspec(dllimport)
#else
#define BLUEMAP_MAPVIEW _declspec(dllexport)
#endif
class BLUEMAP_MAPVIEW MapView : public CView
{
DECLARE_DYNCREATE(MapView)
……………………………………………………动态库代码段
};
#ifndef _BLUEMAP_MAPVIEW_
#ifdef _DEBUG
#pragma comment(lib, "DebugMapView.lib")
#pragma message("debug模式下自动链接DebugMapView.lib")
#else
#pragma comment(lib, "ReleaseMapView.lib")
#pragma message("非debug模式下自动链接ReleaseMapView.lib")
#endif
#endif
以上红色代码使程序在装载动态库时根据当前的编译环境(debug环境或release环境)装入适用不同类型的动态库。
第二步:设置导出动态库的名称
点击动态库工程属性分别设置debug版和release版动态库名称。
设置debug版动态库名称为DebugMapView.dll
设置Release版动态库名称为ReleaseMapView.dll
第三步:编译生成不同版本的动态库文件。
编译为debug版
双击工程的***.def文件
将LIBRARY 后面的文件名改为 DebugeMapView,编译生成动态库文件
编译为Release版
同样的方法,将LIBRARY 后面的文件名改为ReleaseMapView并编译生成动态库文件。
注:为了避免在切换编译模式时不断修改***.def文件,可以再新建一个不同名称的***.def文件并修改工程属性,将Modul Definition file改为合适的*.def文件,这样就不需要每次都修改*.def中的内容了。
接下来再运行前面的单文档工程发现无论是debug模式下或release模式下系统都能正常运行。
个人感觉这是一种不得已的方法,欢迎高手提出更好的方案。