C库在使用gcc/g++编译时无法链接

23

我有一个用于gcc的C库。该库的扩展名为.lib,但始终作为静态库链接。如果我编写一个使用该库作为C代码的程序,一切都可以。但是,如果我将文件重命名为.cpp(做一些在C/C++中都起作用的简单操作),我会得到未定义的引用错误。这些是我为测试目的编写的简单小程序,没有花哨的东西。我使用以下命令进行编译:

gcc -g -Wall -I <path to custom headers> -o program main.c customlibrary.lib -lm -lpthread

上面的方法非常好用,不过:

g++ -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread
或者
gcc -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread -lstdc++

使用自定义库customlibrary.lib时,会导致对任何函数的未定义引用。我尝试创建了一个名为customlibrary.a的符号链接,但是没有成功。

为什么g++无法识别我的库呢?不幸的是,我无法访问库的源代码,但将c-lib链接到c++应该不是问题,对吗?

3个回答

41

你的库似乎是假设从C,而非C++中调用其API。这很重要,因为C++要求从库中导出的符号具有比仅函数名更多的信息。这通过对函数进行“名称重整”来处理。

我假设你的库有一个声明其公共接口的包含文件。为了使其兼容于C和C++,你应该安排告诉C++编译器它所声明的函数应被视为使用C的链接和命名方式。

一个可能简单的测试答案是执行以下操作:

extern "C" {
#include "customlibrary.h"
}

在你的main.cpp中不要直接包含customlibrary.h,而是使用下面的方式:

为了让头文件能够在两种语言中都正常工作,并且正确地将其函数声明为类似于C的形式以供C++使用,在头文件顶部附近加入以下内容:

#ifdef __cplusplus
extern "C" {
#endif

并在底部附近添加以下内容:

#ifdef __cplusplus
}
#endif

1
符号__cplusplus有两个下划线,如相关标准所定义。 - RBerteig

4

C++编译器执行所谓的名称重整 - 出现在代码中的名称与连接器看到的名称不同。解决这个问题的常规方式是告诉编译器某些函数需要C语言链接:

// myfile.cpp
extern "C" int libfun();    // C function in your library

或者对整个头文件进行操作:
// myfile.cpp
extern "C" {
  #include "mylibdefs.h"      // defs for your C library functions
}

2

你的头文件是否具有通常的

#ifdef __cplusplus
extern "C" {
#endif

// ...

#ifdef __cplusplus
} /* extern "C" */
#endif

为了明确地给库函数提供C链接,需要使用extern "C"语法。
.cpp文件默认情况下使用C++链接,即名称重整。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接