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

问题描述

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

例如:

#define MACRO_STRING "Macro String"

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

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

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

在我的代码中的大多数地方,我立即调用 function1,然后是 function2。在我的代码中,字符串“宏字符串”是一个常量。但是一个函数将输入作为 wchar* 而另一个将输入作为 char*

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

解决方法

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

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

请注意,第二个选项会在您的代码库中产生心理开销,您必须记住在传递字符串文字时使用 f1_lit only 以自动调整为宽字符串文字。对于实际的宽字符串文字(以及指向缓冲区的指针),您必须直接调用 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");

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

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

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

再说一次,问题本身的模式是可疑的,因为您没有提供调用两个如此相似的函数背后的推理,只是一个模糊的概念。这些函数还用在什么地方,在运行时处理会不会更好?

可能的 XY problem 材料。

,

快速简便的解决方案,无需额外的宏:

  • 需要 public static int sumOfFirstandLastdigits(int number) { int lastdigit=sumOfFirstandLastdigits(number/10); if(number/10==0) { return number%10; } return lastdigit+sumOfFirstandLastdigits(number%10); } 时直接使用 MACRO_STRING
  • 需要 char * 时使用 L"" MACRO_STRING
,

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

#define ELL(s) L ## s

并使用 ELL 宏包装您的宏:

function1(ELL(MACRO_STRING));