简体   繁体   English

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

[英]How to link app with static library + why this is not working

I have a problem. 我有个问题。 I wrote example code and I want to build it without the error: 我编写了示例代码,并且想要构建没有错误的代码:

main.cpp(.text+0x5): undefined reference to `test()'

Library 图书馆


test1.c test1.c

#include <stdlib.h>
void test()
{
 puts("Działa");
}

test1.h test1.h

#ifndef TEST1_H
#define TEST1_H

extern void test();

#endif

makefile 生成文件

all:
 gcc -c ./src/test1.c -o ./lib/test1.o
 ar rcs ./lib/libtest1.a ./lib/test1.o

Program 程序


main.cpp main.cpp

#include <test1.h>

int main()
{
 test();
 return 0;
}

makefile 生成文件

all:
 g++ -static -I../test1/include -L../test1/lib ./src/main.cpp -o ./build/MyApp -ltest1

What am I doing wrong? 我究竟做错了什么?

You are compiling a C code function, but you are expecting to link a C++ function. 您正在编译一个C代码函数,但是您希望链接一个C ++函数。

Because of 'type safe linkage', the function you provide is not the function that the C++ code calls. 由于“类型安全链接”,您提供的功能不是C ++代码调用的功能。

Either in test1.h use: 在test1.h中使用:

#ifdef __cplusplus
extern "C" {
#endif

extern void test1(void);

#ifdef __cplusplus
}
#endif

Or: 要么:

  • Compile the function with the C++ compiler. 使用C ++编译器编译该函数。

The C++ compiler will mangle the symbol names to provide type-safe linkage (a term which you should be able to search for via your preferred search engine). C ++编译器将对符号名称进行修饰,以提供类型安全的链接(您应该可以通过首选搜索引擎进行搜索的术语)。

The 'compiler' - actually the linker - is looking for a function with a C++ mangled name representing the C++ function with the signature 'void test1(void);'. “编译器”(实际上是链接器)正在寻找具有C ++混淆名称的函数,该名称表示带有签名“ void test1(void);”的C ++函数。

For example (but remember - different compilers deliberately mangle things differently), G++ 4.2.1 on MacOS X 10.6.2 generates a symbol ' __Z5test1v ' for the function; 例如(但要记住,不同的编译器故意处理不同的事情),MacOS X 10.6.2上的G ++ 4.2.1会为该函数生成符号' __Z5test1v '; GCC generates a symbol ' _test1 '. GCC生成符号' _test1 '。 Clearly, when the linker is looking for ' __Z5test1v ', the symbol ' _test1 ' is not going to be used - it is not spelled the same. 显然,当链接程序正在寻找“ __Z5test1v ”时,将不使用符号“ _test1 ”-拼写不相同。 This is a good thing. 这是一件好事。

You can use 'nm -g' on the object file for the main program to see what it is looking for, and on the object file in the library to see what it is providing. 您可以在主程序的目标文件上使用'nm -g'来查看其正在寻找的内容,并在库中的目标文件上使用'nm -g'来查看其提供的内容。 And, given that the spellings are different, that is why the loader does not pick up the library function - it is looking for something with a different name. 并且,由于拼写不同,这就是为什么加载器不选择库函数的原因-它正在寻找名称不同的东西。

You are calling a C function from a C++ function. 您正在从C ++函数调用C函数。 The naming between the two is different (C++ mangles names to include parameter information). 两者之间的命名是不同的(C ++样式名称包含参数信息)。

Change the header file to look like this: 更改头文件看起来像这样:

#ifdef __cplusplus
extern "C" {
#endif

extern void test();

#ifdef __cplusplus
}
#endif

This will tell the compiler that the function follows the C naming/calling convention. 这将告诉编译器该函数遵循C命名/调用约定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM