关于VC中函数名与系统API重名引发的问题。
作者:tyc611.cublog.cn,2008-06-21
这两天使用以前写的一个DLL库时,发现链接出了问题,报错某个成员函数找不到链接,而其它成员没有问题。仔细核对函数名没有发现错误,用dumpbin导出DLL库的符号,也发现确实有这个函数。找了半天,最后才发现导出的函数名多了一个字母(W或A,分别对应于UNICODE版和多字节版)。这更令我感到奇怪了,明明我的函数名没有这个多余的字母。不过,我知道Windows的系统API会有这种命名方式,可能是系统API在作怪。于是,我把该成员函数改了一个名字,错误消失,原来是函数名的原因。以该成员函数名(StartService)在MSDN中搜索,发现确实是一个系统API,且我也确实包含了头文件。把头文件去掉后,用StartService不再有错。因为StartService是中定义的一个宏,因此我的StartService成员函数名被替换了。其实,只要任何包含了的文件都要小心自己命名的函数不要与系统API重名(主要是指那些区分宽窄字符参数的API,此时都使用了宏定义),否则可能引起难以察觉的错误。
这里提供一个重现我的问题的Demo。
主要问题代码(后附完整项目代码):
// MyService.h
#pragma once
#ifdef MY_SERVICE_EXPORTS #define MY_SERVICE_API __declspec(dllexport) #else #define MY_SERVICE_API __declspec(dllimport) #endif
#include <windows.h>
class MY_SERVICE_API MyService { public: MyService(); ~MyService();
void StartService(); void StopService(); };
|
DLL编译链接成功后,运行dumpbin结果如下:
Dump of file TestStartService.lib
File Type: LIBRARY
Exports
ordinal name
(public: __thiscall MyService::MyService( void)) (public: __thiscall MyService::~MyService (void)) (public: class MyService & __thi scall MyService::operator=(class MyService const &)) (public: void __thiscall MySe rvice::StartServiceW(void)) (public: void __thiscall MyServ ice::StopService(void))
Summary
DE .debug$S 14 .idata$2 14 .idata$3 4 .idata$4 4 .idata$5 16 .idata$6 |
如果把注释掉,运行dumpbin结果如下:
Dump of file TestStartService.lib
File Type: LIBRARY
Exports
ordinal name
(public: __thiscall MyService::MyService( void)) (public: __thiscall MyService::~MyService (void)) (public: class MyService & __thi scall MyService::operator=(class MyService const &)) (public: void __thiscall MySe rvice::StartService(void)) (public: void __thiscall MyServ ice::StopService(void))
Summary
DE .debug$S 14 .idata$2 14 .idata$3 4 .idata$4 4 .idata$5 16 .idata$6 |
完整Demo代码:
|
文件: |
TestStartService.zip |
大小: |
3KB |
下载: |
下载 | |
阅读(2515) | 评论(0) | 转发(0) |