我如何在我的命名空间中使用LoadString宏

How can I use the LoadString macros in my namespace?

本文关键字:LoadString 命名空间 我的      更新时间:2023-10-16

当我在命名空间中使用LoadString WinAPI宏时,我有一个问题。我的功能:

namespace Bushman {
    // Get the string from the resource's string table of the module.
    // I use the same name like WinAPI macros but with own signature.
    PTSTR LoadString(HMODULE h, DWORD id) {
        h = NULL == h ? ::GetModuleHandle(NULL) : h;
        PTSTR ptr = NULL;
        // it returns really length instead of concatenated 
        // string length, therefore I can use it for malloc.
        int i = ::LoadString(h, id, (PTSTR)&ptr, 0);
        if (0 == i) {
            return NULL;
        }
        PTSTR string = (PTSTR)malloc(i * (sizeof(TCHAR) + 1));
        ::LoadString(h, id, string, i + 1);
        return string; // NOTE: don't forget free resource in the outer code.
    }
}

我得到编译错误:

'LoadStringW':不是'Bushman'的成员
'LoadStringW':不是'Bushman'的成员
'LoadStringW':不属于"布什曼"

我该如何修复它?

乌利希期刊指南

我认为问题是宏有这样的定义

#ifdef UNICODE
#define LoadString  LoadStringW
#else
#define LoadString  LoadStringA
#endif // !UNICODE

而不是像这样:

#ifdef UNICODE
#define LoadString  ::LoadStringW
#else
#define LoadString  ::LoadStringA
#endif // !UNICODE

乌利希期刊指南2

我找到了问题的原因。问题在我代码的其他地方。我在我的代码中使用了这样的声明:
namespace Bushman {} // namespace declaration
PTSTR Bushman::LoadString(HMODULE h, DWORD id); // function declaration

,但它是错误的。如果我把它重写成这样,一切都可以正常工作:

namespace Bushman {
    PTSTR LoadString(HMODULE h, DWORD id);
}

您有几个选择:

  1. 不包含定义LoadString宏的Windows头文件,或者
  2. 包含头文件,但不定义#undef宏。

这个问题真的没有好的解决办法。一旦你开始使用宏,你就失去了隔离和控制它们影响的能力。预处理器不关心您的名称空间。


关于你对问题的更新,你并没有真正解决问题。正如UPD2中的代码一样,预处理器将LoadString转换为LoadStringW。你只是没有意识到这一点,因为它在编译过程中是透明的。但是,如果您尝试从另一个没有定义LoadString宏的翻译单元使用您的类,您将发现该函数被命名为LoadStringW