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 *
。
我正在寻求有关编写 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 *
。