C++ 如何在C+中导入和导出同名的不同函数+;

C++ 如何在C+中导入和导出同名的不同函数+;,c++,linker,ld,linker-scripts,C++,Linker,Ld,Linker Scripts,我正在为一种自定义语言编写运行时库,在Linux下运行时遇到了一些问题。 我需要创建一个共享对象文件,该文件导出运行时规范指定的符号。 这些名称中的一些与标准库冲突,有些是无效的C++标识符。 在Windows上,我可以简单地将模块定义文件传递给MSVC链接器,但是ld似乎没有提供等效的解决方案。我读过一些关于链接器脚本的内容,发现它们提供了类似的功能,但它们只是部分解决了问题。它们允许我更改导出的名称,因为它不是有效的C++标识符,但会导致新的问题与标准库名称冲突。 行exit=\u ZN7r

我正在为一种自定义语言编写运行时库,在Linux下运行时遇到了一些问题。 我需要创建一个共享对象文件,该文件导出运行时规范指定的符号。 这些名称中的一些与标准库冲突,有些是无效的C++标识符。 在Windows上,我可以简单地将模块定义文件传递给MSVC链接器,但是
ld
似乎没有提供等效的解决方案。我读过一些关于链接器脚本的内容,发现它们提供了类似的功能,但它们只是部分解决了问题。它们允许我更改导出的名称,因为它不是有效的C++标识符,但会导致新的问题与标准库名称冲突。

exit=\u ZN7runtime4exitEi还会导致替换导入的符号,这会在调用
exit
时导致无休止的递归,最终导致segfault(我想这是退出的一种方式)

库源(runtime.cpp):

#包括
命名空间运行时{
[[noreturn]]void\uu cdecl退出(内部代码){
::出口(代码);
}
//不能称之为“不”,因为这是一个关键词
int uu cdecl按位u not(int a){
返回~a;
}
//导出为“对象::.ctor”
void\uuu cdecl对象\u ctor(运行时::对象*实例){
//空的
}
}
MSVC模块定义(exports64.def):

库运行时
出口
退出=?exit@runtime@@YAXH@Z
not=?按位_not@runtime@@YAHH@Z
对象::.ctor=?对象_ctor@runtime@@YAXPEAUobject@1@@Z
链接器脚本(libruntime64.map):

exit=\u ZN7runtime4exitEi;
not=\u zn7运行时11位\u注释i
对象::.ctor=\u ZN7runtime11object\u ctorEPNS\u 6objectE;
/*使用默认链接器脚本*/
第{}节在.text之后插入;
我尝试的另一种方法是使用
ld
--wrap
选项,但这不会更改导出的名称。使用以下代码传递
--wrap=exit
将正确地将
\uuuuuu real\u exit
解析为导入的
exit
函数,但导出的名称仍然是
\uuuuuwrap\u exit

命名空间运行时{
外部“C”[[noreturn]]void\uu real\u exit(内部代码);
外部“C”[[noreturn]]void\uu包装\u退出(内部代码){
__真实出口(代码);
}
}
因此,我想我的问题的核心是:如何链接一个共享对象文件,该文件导入和导出两个具有相同名称的不同符号

如果这是相关的,我使用的前端是Clang,完整的命令行如下所示:

clang-Wl,--script=runtime/libruntime64.map\
-lstdc++-lm-std=c++17\
-fpic-共享-Wl-详细\
-o out/libruntime.so runtime/*.cpp