是否可以从共享库中公开一组 C++ 函数?

Is it possible to expose a set of C++ functions from a shared library?

提问人:yashC 提问时间:11/14/2023 最后编辑:yashC 更新时间:11/14/2023 访问量:70

问:

我有一个共享库和一组我想从该共享库公开的函数。 这些函数是 C++ 函数,即它们不是 .extern c

有人建议我使用命名空间,并有一个公开该命名空间的链接器脚本。我真的不明白这意味着什么,谷歌在这里没有多大帮助。

是否可以直接从共享库公开命名空间中的 C++ 函数,以便当有人 DLOpens SO 时,它会自动在该应用程序的所述名称空间下可用?

工具链:Clang-12 操作系统: Linux based 构建系统:Cmake

C++ 链接器 C++17 共享库

评论

1赞 pptaszni 11/14/2023
通过暴露,您的意思是能够动态加载它?那么也许是这个:stackoverflow.com/a/73549652/4165552dlsym(handle, "myFunctionName"
2赞 Sam Varshavchik 11/14/2023
您必须提供有关操作系统、C++ 编译器和链接器的详细信息。至少在带有 gcc 和 libtool 的 Linux 上,默认情况下,所有全局符号都会从创建的共享库中导出。
1赞 Paul Sanders 11/14/2023
是的,它是(命名空间不是必需的 - 事实上,对于你的第一次努力来说,它可能会使事情复杂化)
1赞 n. m. could be an AI 11/27/2023
如果您不使用 ,您的函数名称将被破坏,这意味着任何希望使用它们的用户都需要知道如何获取其损坏的名称。残缺不全的名字可能看起来像_ZN3Foo3fn1Ev。extern "C"dlsym

答:

1赞 Employed Russian 11/27/2023 #1

是否可以从共享库中公开一组 C++ 函数?

是的。不仅如此,如果你什么都不做,它就会默认发生。

有人建议我使用命名空间,并有一个公开该命名空间的链接器脚本。

你可以这样做,尽管使用 可能会分散注意力。这当然不是必需的。namespace

假设你有这个来源:

namespace Foo {
int fn1() { return 42; }
void fn2() {}
}

void fn3() {}

并且您希望从共享库中导出所有函数,但保留不在内部的函数。namespace Foonamespace Foo

clang++ -fPIC -c f.cc
nm f.o | grep Foo

0000000000000000 T _ZN3Foo3fn1Ev
0000000000000010 T _ZN3Foo3fn2Ev

如您所见,其中的函数很容易识别。然后,您需要的链接器版本脚本是:namespace Foo

{
   global: _ZN3Foo*;
   local: *;
};

把它们放在一起:

clang++ -fPIC f.o -Wl,--version-script=f.lds -shared  -o f.so
nm -D f.so
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000001100 T _ZN3Foo3fn1Ev
0000000000001110 T _ZN3Foo3fn2Ev
                 w __cxa_finalize@GLIBC_2.2.5
                 w __gmon_start__

QED的。