首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么对C函数的C++回调需要“外部C”?

为什么对C函数的C++回调需要“外部C”?
EN

Stack Overflow用户
提问于 2010-04-08 00:31:49
回答 6查看 4.8K关注 0票数 17

我在Boost代码中找到了这样的例子。

代码语言:javascript
复制
namespace boost {
   namespace {
     extern "C" void *thread_proxy(void *f)
     {
       ....
     }

   } // anonymous
   void thread::thread_start(...)
   {
       ...
       pthread_create(something,0,&thread_proxy,something_else);
       ...
   }
} // boost

您到底为什么需要这个extern "C"

很明显,thread_proxy函数是私有的内部函数,我不希望它被修改为"thread_proxy“,因为我实际上根本不需要修改它。

事实上,在我写的所有运行在许多平台上的代码中,我从来没有使用过extern "C",这对于正常的函数来说是可以正常工作的。

为什么要添加extern "C"

我的问题是extern "C"函数污染了全局名称空间,而且它们实际上并不像作者期望的那样是隐藏的。

这不是复制品!我不是在说破坏和外部链接。很明显,在这段代码中,外部链接是不需要的!

回答:C和C++函数的调用约定不一定相同,因此您需要使用C调用约定创建一个。参见C++标准的7.5 (p4)。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-04-08 00:37:54

很明显,thread_proxy函数是私有的内部函数,我不希望它被修改为"thread_proxy“,因为我实际上根本不需要修改它。

无论如何,它仍然会被损坏。(如果不是extern "C"的话)这就是编译器的工作方式。我同意编译器可能会说“这不一定需要修改”,但标准对此只字不提。也就是说,mangling在这里不起作用,因为我们不会尝试链接到函数。

事实上,在我写的所有代码中,我从来没有使用过extern "C",这些代码可以在许多平台上运行,而且它可以按原样使用普通函数。

在不同平台上编写与extern "C"无关。我希望所有标准C++代码都能在具有标准C++兼容编译器的所有平台上工作。

extern "C"与C的接口有关,pthread是的一个库。它不仅不会破坏名称,而且还确保它可以使用C调用约定进行调用。这是需要保证的调用约定,因为我们不能假设我们是在某个编译器、平台或体系结构上运行的,所以尝试这样做的最好方法是使用提供给我们的功能:extern "C"

我的问题是extern "C"函数污染了全局名称空间,并且它们并不像作者期望的那样实际上是隐藏的。

上面的代码没有任何污染。它在一个未命名的名称空间中,并且不能在转换单元之外访问。

票数 17
EN

Stack Overflow用户

发布于 2010-04-08 00:37:48

extern "C"链接并不一定意味着只有名称损坏被抑制。事实上,可能有一种编译器将extern "C"视为不同的调用约定。

该标准将其完全开放为实现定义的语义。

票数 6
EN

Stack Overflow用户

发布于 2010-04-08 00:42:56

这个问题是有效的-尽管该函数被传递到一个C库,但该C库根本没有链接到C++代码。它只给出了函数的地址,所以它对函数的名称没有任何兴趣。

关键是,extern "C"是最接近跨平台的方式,它告诉编译器让函数在该平台上使用标准的C调用约定(即,参数和返回值应该如何在堆栈上传递)。

不幸的是,它还具有在全局级别创建外部链接器符号的副作用。但这可以通过使用像boost_detail_thread_proxy这样的名称来缓解。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2594178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档