c – 命名空间嵌套函数的最佳实践和语义以及extern“C”的使用
我正在创建一个带有C-ABI接口的C库.
这就是GCC如何处理关于重整的外部“C”限定符: namespace x { extern "C" int monkey(int x) { return 1; } int chimpanzee(int x) { return 1; } } 相关的nm输出: 00000000004005cd T _ZN1x10chimpanzeeEi 00000000004005bf T monkey 题: >修复输出标准行为 – 其他主要编译器(特定的MSVC)是否会剥离损坏? 解决方法
这适用于MSVC.
命名空间本身不受名称限制,但在发生名称重整时,命名空间的名称将合并到函数(或对象)的名称中.此过程未记录,但描述为here. 跳转回答你的具体问题: 1)关于名称重整没有标准定义的行为.标准实际上说的是实现为extern“C”构造提供了C兼容的链接: 7.5.3 [链接规范]
complex sqrt(complex); // C + + linkage by default extern "C" { double sqrt(double); // C linkage }
最终这意味着由于C没有命名空间的概念,如果extern“C”函数或命名空间中的对象,导出的名称将失去命名空间限定.这导致… 3)是的,你可能会遇到链接问题.试试这个: main.h #ifndef MAIN_API # define MAIN_API __declspec(dllexport) #endif namespace x { extern "C" MAIN_API void foo(); }; namespace y { extern "C" MAIN_API void foo(); }; main.cpp中 #include <cstdlib> #include <iostream> using namespace std; #define MAIN_API __declspec(dllexport) #include "main.h" void x::foo() { cout << "x::foo()n"; } void y::foo() { cout << "y::foo()n"; } int main() { } 这将发出链接器错误,因为x :: foo()和y :: foo()的extern“C”版本已经丢失了它们的名称空间标识,因此它们最终具有完全相同的名称:foo() 2)关于此的最佳做法.如果必须为命名空间中的函数导出C-ABI,则必须注意最终导出的名称不同.在某种程度上,这首先破坏了使用命名空间的目的.但你可以这样做: #ifndef MAIN_API # define MAIN_API __declspec(dllexport) #endif namespace x { extern "C" MAIN_API void x_foo(); }; namespace y { extern "C" MAIN_API void y_foo(); }; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |