Alles, was nicht
extern "C" deklariert wird, erhält mit einem C++-Compiler "verknautschte"-Symbolnamen, die eine Kodierung der Übergabeparameter enthalten. Das ist für den C++-Linker wichtig, sonst kann der bei überladenen Objektmethoden nicht die anhand der Übergabetypen eindeutige Methode aussuchen. Beispiel:
Code: Select all
extern "C" {
int aaa(void) { return 1; }
}
int bbb(void) { return 1; }
int main(void) {
aaa();
bbb();
return 0;
}
Als x.c abspeichern und kompilieren. Dann die Symbole angucken:
Code: Select all
[jan@janskiste ~]$ g++ -o x x.c
[jan@janskiste ~]$ nm x
08049f08 d _DYNAMIC
08049ff4 d _GLOBAL_OFFSET_TABLE_
080484ec R _IO_stdin_used
w _Jv_RegisterClasses
080483fe T _Z3bbbv
08049ef8 d __CTOR_END__
08049ef4 d __CTOR_LIST__
08049f00 D __DTOR_END__
08049efc d __DTOR_LIST__
080484f0 r __FRAME_END__
08049f04 d __JCR_END__
08049f04 d __JCR_LIST__
0804a010 A __bss_start
0804a008 D __data_start
080484a0 t __do_global_ctors_aux
08048370 t __do_global_dtors_aux
0804a00c D __dso_handle
w __gmon_start__
0804849a T __i686.get_pc_thunk.bx
08049ef4 d __init_array_end
08049ef4 d __init_array_start
08048430 T __libc_csu_fini
08048440 T __libc_csu_init
U __libc_start_main@@GLIBC_2.0
0804a010 A _edata
0804a018 A _end
080484cc T _fini
080484e8 R _fp_hw
080482dc T _init
08048340 T _start
080483f4 T aaa
0804a010 b completed.5701
0804a008 W data_start
0804a014 b dtor_idx.5703
080483d0 t frame_dummy
08048408 T main
Wie du siehst, ist "aaa" unten als Symbol "aaa" vorhanden, während "bbb" zu "_Z3bbbv" wurde. Wenn das mit einer Bibliothek für C geschieht, passen natürlich die Symbole in deinem Programm nicht zu denen in der Bibliothek.
Binde die Include-Dateien der Library also so ein:
Code: Select all
extern "C" {
#include ...
}
Alternativ kannst du die Library ebenfalls mit g++ übersetzen, dann sind die Symbole dort ebenfalls verknautscht und alles passt wieder.
C++ ist halt eine Ansammlung kruder Hacks, um mit den vorhandenen Werkzeugen Dinge zu tun, für die sie eigentlich gar nicht gedacht waren.
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.