Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1073473
  • 博文数量: 77
  • 博客积分: 11498
  • 博客等级: 上将
  • 技术积分: 1840
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-04 11:10
文章分类

全部博文(77)

文章存档

2011年(1)

2010年(16)

2009年(5)

2008年(55)

分类: C/C++

2008-06-21 19:32:24


    关于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) |
给主人留下些什么吧!~~