C 宏应该在一个地方扩展为 char*,在另一个地方扩展为 wchar*,并带有 L 字符

C Macro should expand as char* in one place and wchar* in another place with L character

我正在寻求有关编写 C 宏的帮助,该宏在一个地方扩展为 char* 宏,在另一个地方扩展为 wchar_t* 宏。

例如:

#define MACRO_STRING "Macro String"

到具有函数调用的原子部分:

{
    function1(L"Macro String");
    function2("Macro String");
}

function1 总是接受宽字符 wchar_t *,而 function2 总是接受 char *.

在我的代码中的大多数地方,我调用 function1,紧接着调用 function2。在我的代码中,字符串“Macro String”是一个常量。但是一个函数将输入作为 wchar* 而另一个将输入作为 char*.

需要帮助在两个函数中以不同方式扩展宏

您可以使用另一个添加 L 前缀的宏:

#define ELL(s) L ## s

并使用 ELL 宏包装您的宏:

function1(ELL(MACRO_STRING));

一个宏不知道它周围的上下文——也就是说,它不能根据它的使用位置而做出不同的行为。宏实际上只是 text replacement 的一种形式,只有一些额外的功能。

您必须将宏包装在另一个作为其前缀的宏中,或者将函数调用更改为隐藏此实现细节的宏。

请注意,第二个选项会在您的代码库中产生精神开销,您必须记住在传递 字符串文字时仅使用 f1_lit 自动调整为 宽字符串文字 。对于实际的 宽字符串文字 (和指向缓冲区的指针),您必须直接调用 f1

#define CONCAT(x, y) x ## y
#define L(x) CONCAT(L, x)
#define f1_lit(x) f1(L(x))

#define MYSTRING "hello"

void f1(const wchar_t *s) {
    /* ... */
}

void f2(const char *s) {
    /* ... */
}

int main(void) {
    f1(L(MYSTRING));

    f1_lit(MYSTRING);
    f2(MYSTRING);
}

预处理结果(gcc -E):

f1(L"hello");

f1(L"hello");
f2("hello");

有关为什么需要宏间接寻址的更多详细信息,请参阅 问答。

最好只为两种类型的字符串文字设置两个不同的宏,并在需要时使用适当的宏。

#define MYSTRING "hello"
#define MYSTRING_W L"hello"

话又说回来,问题本身的模式是可疑的,因为你没有提供调用两个这样类似形成的函数背后的推理,只是一个模糊的概念。这些功能还用在哪里,这不是在运行时更好地处理吗?

可能 XY problem material.

一个快速简单的解决方案,没有额外的宏:

  • 需要char *的时候直接使用MACRO_STRING
  • 需要时使用L"" MACRO_STRING wchar_t *