ATL组件中文路径注册问题辨析
(转载请注明来源于
金庆的专栏)
ATL开发一个COM组件,Release MinDependency配置项构建的DLL注册后无法创建对象。原因是DLL注册的路径上有中文。而Debug及Release MinSize编译结果是正常的,或将DLL注册在英文路径上也是好的。
查阅网上的相关文章,可以修改StatReg.h,并定义_ATL_STATIC_REGISTRY来解决。
1.编译环境
在VC6的安装目录的VC98/ATL/Include里面,找到StatReg.h, 中间找到AddString函数,在函数体内的第8行,把
lpszT++;
改为
lpszT=CharNext(lpszT);
2.工程设置
在宏里面添加_ATL_STATIC_REGISTRY。Release MinDependency模式里已经设置了_ATL_STATIC_REGISTRY这个宏。
详见:
ATL组件中文路径注册问题MS承认这是一个错误。
如果动态链接atl.dll就不会有这个问题。
可是一般情况下,大家都不愿依赖atl.dll,所以使用MinDependency选项。
与MinSize配置相比较,区别只有_ATL_DLL和_ATL_STATIC_REGISTRY两个宏定义。显然,MinSize将使用atl.dll。而MinDependency将不会链接atl.dll。
如果删除_ATL_STATIC_REGISTRY将是什么后果?到底是否使用atl.dll?
如果同时_ATL_DLL和_ATL_STATIC_REGISTRY将产生编译错误,而都不定义是可以的,如Debug就是这样。
查看原代码,发现_ATL_DLL将链接atl.lib:
#ifdefined(_ATL_DLL)
#pragmacomment(lib,"atl.lib")
#endif
不定义_ATL_DLL肯定就不会链接atl.lib. 实际上没有_ATL_DLL,将在ATLCOM.H文件中实现所用到的ATL函数,例如:
#ifdef_ATL_DLL
ATLAPIAtlIPersistStreamInit_Load(...);
#else
ATLINLINEATLAPIAtlIPersistStreamInit_Load(...)
...{
...
}
#endif//_ATL_DLL
而_ATL_STATIC_REGISTRY是只管注册的。
#ifdef_ATL_STATIC_REGISTRY
#defineUpdateRegistryFromResourceUpdateRegistryFromResourceS
#else
#defineUpdateRegistryFromResourceUpdateRegistryFromResourceD
#endif
并且_ATL_STATIC_REGISTRY将包含statreg.h头文件。正是这个文件中有错误。
而不定义_ATL_STATIC_REGISTRY就不会出错。在MinDependency中删除这个宏,编译的结果能够正确注册。
因为UpdateRegistryFromResourceS()使用到了statreg.h中的错误函数。而UpdateRegistryFromResourceD()使用的是其它的注册函数。
其实,UpdateRegistryFromResourceD()的注册方法是利用IRegistrar接口,这就是所谓的动态注册。静态注册就是直接调用statreg.h中的函数,动态注册就是调用IRegistrar接口。
调用接口自然要依赖于其它的库,所以删除_ATL_STATIC_REGISTRY虽然能解决问题,可是又增加了依赖性。依赖的库应该还是atl.dll,因为IRegistrar称为ATL注册器。如果IRegistrar实现在atl.dll中,如果atl.dll的版本较低,又不是UNICODE版,动态注册就会出问题,MS说ATL2.0-3.0都是有这个错误的。
参考
[1]
ATL3.0组件注册bug的解决方法 - 激烈振动 - 博客园[2]
CSDN技术中心 ATL组件中文路径注册问题[3]
CSDN技术中心 关于VC向导生成的COM的注册与反注册[4]
ATL.dll问题?[5]
ATL projects built for MinDependency need Atl.dll if the projects use ATL control containment code in Visual C++ 6.0[6]
You receive a "0x80040154 (Class not registered)" error message when you register an ATL serverTAG: 注册,编译,组件,atl,中文路径,COM,静态注册,动态注册
分享到:
相关推荐
mfc visual c++ Atl开发集合组件实例
ATL组件开发程序及在MFCdialog程序中的应用测试
我用ATL开发的dll功能很简单,只是弹出一个对话框显示“Hello ATL!”,但把生成的dll拷贝到别的没有安装VS2010的电脑上无法注册,提示“找不到指定的模块”。
刚开始学习ATL,做了一个简单的小程序练习练习,还有很多不详尽之处
ATL com 组件开发完整实例,需要的可做参考。ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。通过活动模板库,可以建立COM组件,然后通过ASP...
使用ATL开发COM组件文档
ATL创建进程外COM组件服务,包含COM组建客户端测试程序,使用时,需要先通过批处理文件将COM组建服务注册到Windows系统中(win10测试通过),具体可参考我的文章《ATL创建进程外COM组件服务(C++图解说明)》
使用ATL设计组件,写了例子和测试例子,简单明了。
本控件采用VC ATL创建,带有详细的注释和VC调用示例,控件能显示所有图像文件 包括*.BMP; *.JPG; *.cur; *.GIF; *.WMF; *.ico 等,支持图像的平铺,缩放,是学习ATL编程的很好范例。
手写ATLCOM组件示例代码,手写ATLCOM组件示例代码
标准ATL实现,组件源码和使用例程,既是学习ATL的好东西,也可以直接利用。
如何用VS2005 ATL 创建 COM 组件
能显示所有图像格式的控件,ATL组件的开发示例范例集合
ATL COM组建的创建和调用示例, 采用VS进行开发,可参考
初学COM,使用ATL创建COM组件,并测试COM组件的小例子
显示图像控件,ATL组件的开发示例.zip
介绍在VC6.0下如何创建ATL com组件,并提供实例说明如何使用以及释放ATL控件。 另外,ATL组件也可以应用在网页中。
利用ATL编写COM组件,利用ATL编写COM组件,利用ATL编写COM组件,利用ATL编写COM组件
两个 ATL COM 组件源代码参考例子
1、使用ATL建立一个包含2个接口的COM组件,并在其中一个自动化接口中实现字符串的小写转换(如:将HELLO转换成hello);在另一个普通的接口中实现2个方法:通过三角形的3条边长求面积和两数之间的除法()(如:a/b...