如何将应用程序与静态库链接+为什么这不起作用

BPS*_*BPS 0 c c++ linux gcc g++

我有个问题.我编写了示例代码,我想在没有错误的情况下构建它:

main.cpp(.text+0x5): undefined reference to `test()'
Run Code Online (Sandbox Code Playgroud)

图书馆


test1.c

#include <stdlib.h>
void test()
{
 puts("Dzia?a");
}
Run Code Online (Sandbox Code Playgroud)

test1.h

#ifndef TEST1_H
#define TEST1_H

extern void test();

#endif
Run Code Online (Sandbox Code Playgroud)

生成文件

all:
 gcc -c ./src/test1.c -o ./lib/test1.o
 ar rcs ./lib/libtest1.a ./lib/test1.o
Run Code Online (Sandbox Code Playgroud)

程序


main.cpp中

#include <test1.h>

int main()
{
 test();
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

生成文件

all:
 g++ -static -I../test1/include -L../test1/lib ./src/main.cpp -o ./build/MyApp -ltest1
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Jon*_*ler 10

您正在编译C代码函数,但您希望链接C++函数.

由于'类型安全链接',您提供的功能不是C++代码调用的函数.

在test1.h中使用:

#ifdef __cplusplus
extern "C" {
#endif

extern void test1(void);

#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)

要么:

  • 使用C++编译器编译该函数.

C++编译器将破坏符号名称以提供类型安全链接(您应该能够通过首选搜索引擎搜索的术语).

'编译器' - 实际上是链接器 - 正在寻找一个带有C++错位名称的函数,该名称代表带有签名'void test1(void);'的C++函数.

例如(但请记住 - 不同的编译器故意以不同的方式破坏事物),MacOS X 10.6.2上的G ++ 4.2.1 __Z5test1v为函数生成符号' '; GCC生成一个符号' _test1'.显然,当链接器正在寻找' __Z5test1v'时,符号' _test1'将不会被使用 - 它的拼写不相同.这是一件好事.

您可以在主程序的目标文件上使用'nm -g'来查看它正在查找的内容,并在库中的目标文件上查看它提供的内容.并且,鉴于拼写不同,这就是加载器没有获取库函数的原因 - 它正在寻找具有不同名称的东西.