这就是GCC如何处理关于重整的外部“C”限定符:
namespace x { extern "C" int monkey(int x) { return 1; } int chimpanzee(int x) { return 1; }}
相关的nm输出:
00000000004005cd T _ZN1x10chimpanzeeEi00000000004005bf T monkey
题:
我想在命名空间中保留C-ABI中涉及的函数,以便最大程度地重用.重要说明:编译库后,我将为链接器提供映射文件(GCC)或模块定义文件(MSVC).
>修复输出标准行为 – 其他主要编译器(特定的MSVC)是否会剥离损坏?
>当他们涉及外部ABI时,他们在名称空间中放置函数的任何陷阱或最佳实践是什么?
>这是否会干扰链接时间内去除功能的C-ABI导出?
命名空间本身不受名称限制,但在发生名称重整时,命名空间的名称将合并到函数(或对象)的名称中.此过程未记录,但描述为here.
跳转回答你的具体问题:
1)关于名称重整没有标准定义的行为.标准实际上说的是实现为extern“C”构造提供了C兼容的链接:
7.5.3 [链接规范]
Every implementation shall provIDe for
linkage to functions written in the C
programming language,“C”,and linkage
to C + + functions,“C++”. [Example:
complex sqrt(complex); // C + + linkage by default extern "C" { double sqrt(double); // C linkage }
—end example]
最终这意味着由于C没有命名空间的概念,如果extern“C”函数或命名空间中的对象,导出的名称将失去命名空间限定.这导致…
3)是的,你可能会遇到链接问题.试试这个:
main.h
#ifndef MAIN_API# define MAIN_API __declspec(dllexport)#endifnamespace 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)#endifnamespace x{ extern "C" MAIN_API voID x_foo();};namespace y{ extern "C" MAIN_API voID y_foo();};总结
以上是内存溢出为你收集整理的c – 命名空间嵌套函数的最佳实践和语义以及extern“C”的使用全部内容,希望文章能够帮你解决c – 命名空间嵌套函数的最佳实践和语义以及extern“C”的使用所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)