【问题标题】:How to link a C++ shared library with gcc如何将 C++ 共享库与 gcc 链接
【发布时间】:2012-06-25 06:38:05
【问题描述】:

我看到一个带有 C++ 共享库的 GCC 链接,但我无法自己复制它。所以首先我创建了一个带有 testfunction 的 C++ 库:

g++ -shared -o libtest.so test.c

然后我有一个测试主函数,它调用库函数并像这样编译它

gcc -o prog.out main.c -L. -ltest

然后我收到错误

undefined reference to 'testfunc'

我认为这是由库中的不同引用引起的...C 将函数命名为 testfunc,而 C++ 将函数命名为 [一些东西]__testfunc [也许又是一些东西]。

我也试过

gcc -o prog.out main.c -l:libtest.so

但这会导致同样的错误。

因此,我的问题是:如何将带有 gcc 的 c++ 库链接到 c 文件?

更新:我知道我可以使用extern "C",但这不是解决问题的方法。也许链接器有一些参数?

Update2:只是认为第一部分也有可能只是用 c++ 编译并与 gcc 链接。也试过这个:

g++ -c testlib.c -o testlib.o
gcc -shared -o libtest.so testlib.o
gcc -o prog.out -l:libtest.so

还是不行。标志有问题吗?

【问题讨论】:

  • “这不是解决方法”是什么意思?我告诉你,解决问题的方式,除非有什么你没有告诉我们。
  • @Dietrich Epp 看起来就像我在 Update2 中写的那样。而且我确信它没有完成'extern' - 如果你想看看这个项目:openjdk

标签: c++ c linker shared-libraries


【解决方案1】:

是的,问题与共享库无关(我认为...),而与名称修改有关。

在你的头文件中,你必须像这样声明函数:

#ifdef __cplusplus
extern "C" {
#endif

void testfunc(void);

#ifdef __cplusplus
}
#endif

这将导致testfunc 在 C 和 C++ 中具有相同的符号和调用约定。

在我现在使用的系统上,C 符号名称将是 _testfunc,而 C++ 符号名称(假设您使用 extern "C")将是 __Z8testfuncv ,它对有关参数类型的信息进行编码,因此重载将正常工作。比如void testfunc(int x)变成__Z8testfunci,不会和__Z8testfuncv发生冲突。

【讨论】:

    【解决方案2】:

    当您使用 g++ 时,它会将 ALL 源代码编译为 C++。这意味着所有函数都使用 C++ ABI(这也包括名称修饰)。当您使用 gcc 时,它会使用 C ABI 编译 *.c 文件(无名称修改)。

    因此,使用两个不同的编译器编译相同的函数会生成不同的函数(在很多方面)。那是因为它们是不同的语言

    强制 g++ 使用 C ABI 编译函数,前缀为 extern "C"

    extern "C" void testfunc(char*);
    

    或者使用块版本

    extern "C" {
    <multiple Functions>
    }
    

    说实话,我再也没有用 gcc 编译过任何东西(除非有一些硬性要求这样做(在这种情况下,我通常会修复代码以便它可以在 C++ 中工作))。如果你用 g++ 编译所有文件只会让过程更简单。

    【讨论】:

      【解决方案3】:

      如果您确定这不是因为名称混淆。那么这意味着 gcc 找不到库尝试给出库的完整路径,除非 .so 文件位于标准位置。如果您不确定,请重新检查变量(函数)名称中的任何冲突。使用命名空间对类进行分组,并在类内部定义函数以避免命名冲突

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-14
        • 2016-01-18
        • 2010-10-18
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 1970-01-01
        相关资源
        最近更新 更多