dlopen() mit externen Arrays

16/04/2010 - 09:22 von Ole Streicher | Report spam
Hallo,

ich habe eine Weile nicht mehr in C programmiert und stehe gerade auf
dem Schlauch.

Ein Teil meines Programms ist in eine dynamisch anlinkbare Bibliothek
ausgelagert. Von dort muss ich auf ein Array von Zeichenketten
zugreifen. Dieses Array wird entsprechend mit

extern char* mydefines[];

deklariert. Nur leider meckert dlopen() dann über nicht aufgelöste
Symbole herum und weigert sich, die Bibliothek auch nur zu öffnen.

Ersetze ich die Deklaration durch

extern char **mydefines_as_pointer;

funktioniert es.

Warum? (Linux, libc-2.9)

Viele Grüße

Ole
 

Lesen sie die antworten

#1 Jan Seiffert
16/04/2010 - 15:07 | Warnen spam
Ole Streicher schrieb:
Hallo,

ich habe eine Weile nicht mehr in C programmiert und stehe gerade auf
dem Schlauch.

Ein Teil meines Programms ist in eine dynamisch anlinkbare Bibliothek
ausgelagert. Von dort muss ich auf ein Array von Zeichenketten
zugreifen. Dieses Array wird entsprechend mit

extern char* mydefines[];

deklariert. Nur leider meckert dlopen() dann über nicht aufgelöste
Symbole herum und weigert sich, die Bibliothek auch nur zu öffnen.

Ersetze ich die Deklaration durch

extern char **mydefines_as_pointer;

funktioniert es.


Warum? (Linux, libc-2.9)




Das weiss ich auch nicht genau, aber ne Vermutung:

Bist du sicher das es _echtes_ C ist und nicht C++?

Der runtime (und der normale) linker arbeiten mit nackten Symbolnamen, einfachen
Strings. Dem ist scheiss egal was er da zusammen linkt.
Du kannst auch eine Funktion mit Code als Array von Integer linken, ist im total
Latte. Hauptsache der Name passt zusammen.

Damit C++ sowas wie
my_func(int)
my_func(float)
machen kann, macht es Namemangeling. Der nackte Symbolname (my_func) wird mit
einem haufen von "Escape-" und "Steuerzeichen" aufgefuellt um den Typ (oder die
Typen + Klasse + Namespace + etc...) zu encodieren und das Symbol "eindeutig" zu
machen.
Der (runtime) linker weiss nix von C++, er sieht dann statt dem C-ueblichen
"my_func" eben "Zasdf_my_func", auch nur ein string, den es dann "brav" aufloesst.

Das Problem ist, das natuerlich auf beiden Seiten der Typ haargenau und damit
das mangeling haargenau passen muss (C++ ist mit Typen etwas anal).

Schau mal in der .so mit nm oder objdump wie genau das Symbol heisst (es muesste
ein U fuer undefined Symbol sein) oder am Programm was da nun exportiert wird.
Pass auf das nm oder objdump _nicht_ automatisch C++ demangeling machen (sonst
sieht das nach einfach "mydefines_as_pointer" aus aber in wirklichkeit ist es
"Zadguigeiguhfadi_my_defines_as_pointer").

Du koenntest dann mal mit sowas wie:

#ifdef __cplusplus
extern "C" {
#endif
extern char *mydefines_as_pointer[];
#ifdef __cplusplus
};
#endif

(oder so aehnlich) auf beiden Seiten rumspielen.

Viele Grüße

Ole


Gruss
Jan

Miksch's Law:
If a string has one end, then it has another end.

Ähnliche fragen