Forum: PC-Programmierung C/C++ in gemeinsame Bibliothek kompilieren (GCC)


von Philip K. (philip_k)


Lesenswert?

Hallo,

Ich habe eine Software, die im wesentlichen aus C-Code besteht. Nun 
möchte ich aus diesem Code ein Modul aufrufen, das in C++ geschrieben 
ist.
Dafür habe ich für den C++-Code eine C-API geschrieben.
Der gesamte Code soll in eine statische lib compiliert werden, was auch 
fehlerfrei funktioniert. Nur kann wenn ich diese lib in einem anderen 
Programm verwenden möchte der linker die Symbole der C-API Funktionen 
nicht auflösen und ich verstehe nicht warum.

Compiler gcc/g++, Cross-Compile für Linux aus Cygwin.

Ich versuche mal mit einem Beispiel darzustellen, wie ich das gemacht 
habe:
test.c:
1
#include "cpp_api.h"
2
void test()
3
{
4
   cpp_function();
5
}

cpp_api.h:
1
   void cpp_function();

cpp_api.cpp
1
   extern "C" void cpp_function()
2
   {
3
      ...
4
   }

Wenn ich das ganze in test.a compiliere und "nm -g test.a" aufrufe 
bekomme ich auszugsweise sowas:
1
test.o:
2
...
3
    U cpp_function
4
5
cpp_api.o:
6
...
7
    T _cpp_function

Laut nm-Manual (habe das tool gerade erst entdeckt und kenn mich nicht 
aus...) steht das U für Unresolved. Ist das an der Stelle normal, weil 
die Funktion in einem anderen object-file steht? Und warum hat 
cpp_funtion in cpp_api.o einen führenden Unterstrich?

Jedenfalls sagt der Linker, der test.a einbinden soll "...undefined 
symbol: cpp_funtion"

Was mache ich falsch?

von Peter II (Gast)


Lesenswert?

cpp_api.h:

   void cpp_function();


schreibe dort auch mal das extern "c" rein.

von Rene H. (Gast)


Lesenswert?

Wie kompilierst Du den c++ code und wie den c code . Stichwort: name 
mangling.

Grüsse,
René

von Philip K. (philip_k)


Lesenswert?

Rene H. schrieb:
> Wie kompilierst Du den c++ code und wie den c code . Stichwort: name
> mangling.
Die .ccpp-files werden mit g++, die .c-files mit gcc compiliert.

Peter II schrieb:
> cpp_api.h:
>
>    void cpp_function();
>
> schreibe dort auch mal das extern "c" rein.
Ich habs mal so gemacht:
1
#ifdef __cplusplus
2
extern "C"
3
{
4
#endif
5
   void cpp_function();
6
#ifdef __cplusplus
7
}
8
#endif

Am Inhalt der nm-Ausgabe ändert es nichts, ob ich überhaupt irgendwo 
extern "C" hin schreibe. Da steht immer _cpp_function.

von Rolf Magnus (Gast)


Lesenswert?

Philip K. schrieb:
> Cross-Compile für Linux aus Cygwin.

Warum macht man denn sowas?

Philip K. schrieb:
> Die .ccpp-files werden mit g++, die .c-files mit gcc compiliert.

Das ist aber falsch. Du mußt dann schon den Cross-Compiler nehmen. gcc 
und g++ sind die nativen Compiler.

von Philip K. (philip_k)


Lesenswert?

Rolf Magnus schrieb:
> Warum macht man denn sowas?
Das ist halt so vorgegeben... :-) Beim Zielsystem handelt es sich um ein 
sehr abgespecktes embedded Linux ohne Compiler. Wie würdest Du denn da 
entwickeln? VM?

> Philip K. schrieb:
>> Die .ccpp-files werden mit g++, die .c-files mit gcc compiliert.
>
> Das ist aber falsch. Du mußt dann schon den Cross-Compiler nehmen. gcc
> und g++ sind die nativen Compiler.
Vielleicht hab ich mich auch falsch ausgedrückt...auf dem Cygwin 
befindet sich eine Toolchain für die Zielarchitektur. Die funtioniert 
auch - mit reinen C oder C++ Programmen gibt es keine Probleme.

von Rolf Magnus (Gast)


Lesenswert?

Philip K. schrieb:
> Rolf Magnus schrieb:
>> Warum macht man denn sowas?
> Das ist halt so vorgegeben... :-) Beim Zielsystem handelt es sich um ein
> sehr abgespecktes embedded Linux ohne Compiler. Wie würdest Du denn da
> entwickeln? VM?

Bisher habe ich das immer auf einem anderen Linux-System mit Compiler 
gemacht. ;-)
Wir haben aber einmal tatsächlich auch mal Cross-bauen unter Cygwin 
probiert. Hat im Prinzip funktioniert, war aber elends langsam. 
Wahrscheinlich weil der Build-Prozess sehr viel forkt und schnelles 
Kopieren eines Prozesses nicht gerade eine Stärke von Windows ist.

Philip K. schrieb:
>> Philip K. schrieb:
>>> Die .ccpp-files werden mit g++, die .c-files mit gcc compiliert.
>>
>> Das ist aber falsch. Du mußt dann schon den Cross-Compiler nehmen. gcc
>> und g++ sind die nativen Compiler.
> Vielleicht hab ich mich auch falsch ausgedrückt...auf dem Cygwin
> befindet sich eine Toolchain für die Zielarchitektur.

Aber die heißt vermutlich nicht einfach nur gcc.

> Die funtioniert auch - mit reinen C oder C++ Programmen gibt es keine
> Probleme.

Das mit dem führenden Unterstrich ist halt was, das unter Windows gerne 
gemacht wird, deshalb dachte ich, du hast vielleicht den falschen 
Compiler genutzt.

von Philip K. (philip_k)


Lesenswert?

Rolf Magnus schrieb:
> Wir haben aber einmal tatsächlich auch mal Cross-bauen unter Cygwin
> probiert. Hat im Prinzip funktioniert, war aber elends langsam.
Das kann ich allerdings bestätigen. Leider habe ich momentan kein 
Linux-System zur Verfügung.

> Aber die heißt vermutlich nicht einfach nur gcc.
Das stimmt :-)

Ich frage mich jetzt allerdings warum der compiler offenbar trotz extern 
"C" deklaration ein name mangeling macht...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Nach Name-Mangling sieht das nicht aus, eher unterschiedliche ABIs was 
"leading underscores" in Symbolnamen angeht.

Selbst wenn dein gcc -f[no-]leading-understcores [1] unterstützt, ist 
das nicht unbedingt die Lösung.

Was gehen sollte, ist im Assembler ein anderes Symbol ausgeben zu lassen 
[2], hier ein Beispiel weil die neulich überarbeitete GCC-Doku nicht 
richtig darstellt:
1
extern void cpp_func (void) __asm ("_cpp_func");
2
3
void cpp_func ()
4
{
5
    /***/
6
}

Allerdings verwundert es schon, daß C und C++ so schlecht 
zusammenpassen...


--

[1]
http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fleading-underscore-2631

[2]
http://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html

von Philip K. (philip_k)


Lesenswert?

Ok, das werd ich mal probieren.
Blöde Frage: sieht der asm-Aufruf anders aus, wenn die Funktion 
Rückgabewerte/Parameter hat?

von Philip K. (philip_k)


Lesenswert?

Rolf Magnus schrieb:
> Das ist aber falsch. Du mußt dann schon den Cross-Compiler nehmen. gcc
> und g++ sind die nativen Compiler.

Aaargh! Das war jetzt doch der Grund. Die passende Toolchain war nur für 
den C-Compiler gesetzt, für C++ wurde der cygwin-g++ verwendet.
Jetzt gehts...danke für die Mühe!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.