当前位置:  开发笔记 > 编程语言 > 正文

static vs extern"C"/"C++"

如何解决《staticvsextern"C"/"C++"》经验,为你挑选了2个好方法。

静态成员函数和extern"C"链接函数之间有什么区别?例如,在C++中使用"makecontext"时,我需要传递一个指向函数的指针.谷歌建议使用extern"C"链接,因为"makecontext"是C.但我发现使用静态工作也是如此.我只是幸运还是......

class X {
   public:
   static void proxy(int i) {}
}
makecontext(..., (void (*)(void)) X::proxy, ...);

VS

extern "C" void proxy(int i) {}
makecontext(..., (void (*)(void)) proxy, ...);

编辑:你能展示静态成员版本不起作用的编译器或架构(并且它不是编译器中的错误)吗?



1> Johannes Sch..:

是的,你只是幸运:) extern"C"是C语言的一种语言链接,每个C++编译器都必须支持,除了默认的extern"C++".编译器可能支持其他语言链接.例如,GCC支持extern"Java",它允许与java代码接口(虽然这非常麻烦).

extern"C"告诉编译器你的函数可以被C代码调用.这可以但不是必须包括适当的调用约定和适当的C语言名称修改(有时称为"装饰")等,具体取决于实现.如果你有一个静态成员函数,它的调用约定是你的C++编译器之一.它们通常与该平台的C编译器相同 - 所以我说你很幸运.如果你有一个C API并且你传递了一个函数指针,那么最好总是把一个放到用extern"C"声明的函数中

extern "C" void foo() { ... }

即使函数指针类型不包含链接规范,但看起来像

void(*)(void)

链接是类型的组成部分 - 如果没有typedef,你就无法直接表达它:

extern "C" typedef void(*extern_c_funptr_t)();

严格模式下的Comeau C++编译器将发出错误,例如,如果您尝试将上面的extern"C"函数的地址分配给a (void(*)()),因为这是指向具有C++链接的函数的指针.



2> dirkgently..:

注意,这extern C是C/C++互操作性的推荐方式.这是主人谈论它.添加到eduffy的答案:请注意,不推荐使用全局命名空间中的静态函数和变量.至少使用匿名命名空间.

回到extern C:如果你不使用extern C,你必须知道确切的受损名称并使用它.这更令人痛苦.

推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有