ATL组件中文路径注册问题辨析

来源:互联网 发布:华为软件应用市场 编辑:程序博客网 时间:2024/04/29 20:58
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:
#if defined(_ATL_DLL)
    
#pragma comment(lib, "atl.lib")
#endif

不定义_ATL_DLL肯定就不会链接atl.lib. 实际上没有_ATL_DLL,将在ATLCOM.H文件中实现所用到的ATL函数,例如:
#ifdef _ATL_DLL
ATLAPI AtlIPersistStreamInit_Load(...);
#else
ATLINLINE ATLAPI AtlIPersistStreamInit_Load(...)
{
    ...
}

#endif //_ATL_DLL

而_ATL_STATIC_REGISTRY是只管注册的。
#ifdef _ATL_STATIC_REGISTRY
#define UpdateRegistryFromResource UpdateRegistryFromResourceS
#else
#define UpdateRegistryFromResource UpdateRegistryFromResourceD
#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 server

 TAG: 注册,编译,组件,atl,中文路径,COM,静态注册,动态注册
原创粉丝点击