VC2005和VC6的编译环境,库的支持有诸多的不同,所以直接迁移有很多无法预料的风险。目前遇到的主要问题如下:
1. MFC类库有些类的接口定义已发生改变,如CRichEditCtrl::CreateEx函数,CWnd:: OnActivateApp消息相应函数。
2. 库支持方面的更改,目前ToolsSDK库是VC6环境下编译的,其中有些函数依赖于VC6下的一些特定库,直接把VC6下的库拷贝过来可能会有无法预测的风险。
3. VC2005和VC6的项目生成向导生成的代码框架差别比较大,这其中可能一有些类引用依赖的宏发生改变。
4. COM的支持变动较大。
鉴于上面的原因和一些目前尚不明了的隐患,建议先用VC2005向导建立项目框架,然后在逐步加入现有的代码文件,这样编译环境相对干净,排查问题也少走弯路。
解决方案:
对于第一点,可以使用_MSC_VER宏来控制,1400为VC2005编译器版本号。可用如下代码对变动的函数接口加以控制:
#if _MSC_VER == 1400 // VC 2005
afx_msg void OnActivateApp(BOOL bActive, DWORD hTask);
#else
afx_msg void OnActivateApp(BOOL bActive, HTASK hTask);
#endif
第二个问题,有些lib库,在VC6下编译生成,依赖于MFC42.lib这个VC6提供的库,VC2005链接是会提示找不到MFC42.lib这个库。所以,直接把VC6编译的库的源代码加入到VS2005项目中,然后编译可以通过,经验证,运行也没有问题。
第三个问题,受影响较大的是COM项目,COM采用重建的方法(有点土:p)
最后一个问题主要是VC6中的一些COM的全局变量,主要是CComModule _Module这个对象。在VC2005中,ATL为7.0,CComModule已经舍弃了,取而代之的是CAtlDllModuleT模板类,向导会在DLL导出函数实现(DllMain所在的.cpp文件)中自动生成一个继承自CAtlDllModuleT的类,如:
class CXXXModule : public CAtlDllModuleT< CXXXModule >
{
public :
DECLARE_LIBID(LIBID_XXXLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_XXX, "{16E6FC24-0E4F-4669-B114-09A16D9068E8}")
};
CXXXModule _AtlModule;
可以看出_AtlModule取代了VC6中的CComModule实例,其类型CQDSkinModule是继承自CAtlDllModuleT模板类,它代表这个DLL模块。
由于CXXXModule是定义在.cpp文件中,有时候我们难免需要用到_AtlModule这个实例,怎么办?查看atlbase.h文件,template<T> CAtlDllModuleT是继承自模板CAtlModuleT<T>这个模板类的,而CAtlModule<T>又是继承自CAtlModule,类层次图如下:
并且在atlbase.h头文件中,定义了一个CAtlModule* _pAtlModule指针,在CAtlModule的默认构造函数中,会对_pAtlModule做如下初始化
_pAtlModule = this;
所以,我们只要包含atlbase.h这个头文件,就可以通过_pAtlModule应用到CQDSkinModule _AtlModule这个对象了。