从C++链接到 C 库:为什么并不总是需要 extern?
Linking to C libraries from C++: why isn't extern always needed?
通常要让C库在C++中工作,必须将其包含在extern "C" { #include <clibrary.h> }
中。许多库将在其头文件中包含类似#ifdef __cplusplus extern "C" { ...
的代码,以使它们对C++代码(例如pthread.h
)更加友好。有时情况并非如此。例如,stdio.h
没有这样的#ifdef
,但我仍然可以编译&使用C++编译器链接常用的#include <stdio.h> int main() {printf("Hello");}
,而不将其封装在extern "C"
语句中。为什么会这样?
通常要让一个C库在C++中工作,必须将其包含在
extern "C" { #include <clibrary.h> }
中。
只有在设计库时没有考虑到C++兼容性。但这是一个黑客。
许多库将在其头文件中包含类似
#ifdef __cplusplus extern "C" { ...
的代码,以使它们对C++代码(例如pthread.h
)更友好
是的,一个好的库可以做到这一点。
因此,您不需要也不应该在#include
周围添加另一个extern "C"
。
stdio.h
是一个将正确执行此操作的标头示例(见下文)。
例如,
stdio.h
没有这样的#ifdef
当然可以!跟随金钱轨迹…
为什么不总是需要extern?
所以,总之,只有当头文件的作者没有为你做这件事时,你才需要自己做。当头文件的作者这样做时,你不需要这样做。
例如,stdio.h没有这样的#ifdef
可能是这样。无论如何,<stdio.h>
是由C++标准库(继承自C标准库)提供的头。它保证在没有extern "C"
的情况下工作,就像所有标准标头一样。
请注意,在当前版本的标准中,不赞成在C++中使用继承的标准标头的<name.h>
名称而不是<cname>
,并且已被确定为在未来的修订中删除的候选名称。
为什么不总是需要extern?
这只是因为有些头文件是直接为支持C++而编写的,所以它们自己也支持C++。
- 为什么在全局范围内使用"extern int a"似乎不行?
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 为什么这"undefined extern variable"不会导致 C++17 中出现链接器错误?
- 关于std::cout,为什么使用"extern"比"singleton pattern"
- 为什么我不能在标头中只定义一个非常量 gloabal 变量?如果我使用命名空间,为什么我必须声明它"extern"?
- 如果仅使用一个翻译单元使用Extern模板类,为什么我不会遇到链接错误
- 为什么他们坚持在下面的示例中使用"extern"说明符?
- 为什么"extern int &c;"工作正常?
- 从C++链接到 C 库:为什么并不总是需要 extern?
- 为什么EXTERN_C宏在其C形式中省略了"EXTERN"
- 为什么我应该使用extern关键字来声明命名空间范围中的变量
- 为什么C++编译器允许 extern 关键字与定义相结合
- 为什么这个 extern "C" 函数不能使用 python ctypes 工作?
- 当使用extern在文件之间共享常量时,为什么定义中需要extern
- 为什么要定义"SQLITE_EXTERN extern"
- 将 dll 方法从C++导出到 C#。为什么我需要:" extern " C " "
- 为什么跨多个文件共享时不需要用"extern"装饰"const char *"
- 为什么使用static、extern和不使用static声明的变量包含不同的值
- 为什么"extern template"不能与shared_ptr合作?
- 为什么"extern const int n;"不能按预期工作?