开发者

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

开发者 https://www.devze.com 2022-12-24 07:06 出处:网络
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()\'

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

#include <stdlib.h>
void test()
{
 开发者_开发技巧puts("Działa");
}

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

#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.

Because of 'type safe linkage', the function you provide is not the function that the C++ code calls.

Either in test1.h use:

#ifdef __cplusplus
extern "C" {
#endif

extern void test1(void);

#ifdef __cplusplus
}
#endif

Or:

  • Compile the function with the C++ compiler.

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).

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);'.

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; GCC generates a symbol '_test1'. Clearly, when the linker is looking for '__Z5test1v', the symbol '_test1' is not going to be used - it is not spelled the same. 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. 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. The naming between the two is different (C++ mangles names to include parameter information).

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消