Seite 1 von 1

C-function in einem Constructor aufrufen

Verfasst: 18. November 2007 22:39
von qtNiko
hallo,

ist es generell möglich, innerhalb eines Konstruktors eine C-function aufzurufen, die in einer anderen Datei definiert ist?

Folgende Situation liegt vor:
Ich habe C-Code, der in meinem Qt-Programm verwendet werden soll. Das h-File fname.h:

Code: Alles auswählen

...
typedef struct{
       int nflag;
      ...
   } F_CONFIG;
   
F_CONFIG * get_config_ptr();
Das C-File fname.c dazu:

Code: Alles auswählen

#include "fname.h"

static F_CONFIG b_config;   // das hat seine Gründe

F_CONFIG * get_config_ptr()
{
   return (&b_config);
}
und hier noch die relevante Implementierung, fparams.cpp, in meinem Qt-Programm:

Code: Alles auswählen

#include "fname.h"
F_CONFIG * pb_config;   
.. Konstruktor einer Klasse :
{ ...
  pb_config = get_config_ptr();        <------ hier meldet der Compiler einen Fehler
... }

..::on_OKButton_clicked()
{ ...
  pb_config->nflag = 0;
...
}
Die Fehlermeldung des Compilers: undefined reference to 'get_config_ptr()'

Ich verstehe nicht, warum der Compiler get_config_ptr() nicht kennt. Es ist doch fname.h als Include angegeben.

Der Versuch, die ersten beiden Zeilen von fparams.cpp in die Klassendefinition zu verschieben, ergibt die gleiche Fehlermeldung.

Das Problem ist vermutlich nicht Qt-spezifisch, aber vielleicht kann es ja dennoch hier gelöst werden.

Danke für Tipps

Verfasst: 19. November 2007 02:07
von CLRS530
Du solltest schon richtig gucken :-P Ich nehme mal stark an, dass das vom Linker und nicht vom Compiler ausgespuckt wurde, was ein beträchtlichen Unterschied macht.
Wie auch immer du das Kompilierst, der Fehler wird wohl da zu suchen sein (Makefile etc...)

Verfasst: 19. November 2007 22:00
von qtNiko
nun, das Make-File wird von qmake erstellt. Da mache ich selber gar nichts dran.

Verfasst: 20. November 2007 09:39
von solarix
du musst den C++-Compiler mitteilen, dass du C-Funktionen (nicht C++) hast...

http://www.parashift.com/c++-faq-lite/m ... d-cpp.html

einmal gut durchlesen, dann funktioniert auch dein build...

Verfasst: 20. November 2007 14:12
von kitov
Das ist eine Fehlermeldung vom Linker , Bibliothek mit der Implementierung der Funkiton fehlt .

Verfasst: 20. November 2007 14:20
von solarix
kitov hat geschrieben:Das ist eine Fehlermeldung vom Linker , Bibliothek mit der Implementierung der Funkiton fehlt .
Wenn beide Source-Dateien in der Qt-Profile eingetragen sind, ist diese Aussage quatsch... die Implementierung ist vorhanden, hat jedoch einen anderen Symbol-Namen.. deshalb:

http://www.parashift.com/c++-faq-lite/m ... d-cpp.html

Verfasst: 20. November 2007 14:53
von kitov
Du hast recht , sourcefile ist vorhanden , hab flasch geguckt :-)

Verfasst: 20. November 2007 23:27
von qtNiko
solarix hat geschrieben:du musst den C++-Compiler mitteilen, dass du C-Funktionen (nicht C++) hast...

http://www.parashift.com/c++-faq-lite/m ... d-cpp.html

einmal gut durchlesen, dann funktioniert auch dein build...
Das habe ich jetzt versucht, aber zunächst hatte es auch nicht geklappt. Mittlerweilen funktioniert es nach verschiedenen Versuchen. Aber mir ist nicht recht klar, warum es vorher nicht und jetzt schon funktioniert.

Da die C-functions auch in einem C-Programm verwendet werden sollen, wählte ich aus Kompatibilitätsgründen die Lösung 32.3 aus obiger url. Ich möchte nämlich vermeiden, dass die bestehenden Dateien mit C-functions geändert werden müssen.

Während der Suche nach einer Lösung probierte ich noch andere Wege:

2. Versuch:
In obiger url, 32.1, steht, dass alles ganz einfach sei, wenn alles mit g++ compiliert würde.
Ich stellte fest, dass qmake ein Makefile so erzeugt, dass stets eine Datei *.c mit gcc und nicht g++ compiliert wird. Daher überlistete ich versuchsweise den Compiler und benannte fname.c in fname.cpp um.
Auf diese Weise hat alles geklappt, allerdings um den Preis der Umbenennung der C-Dateien (ich habe sehr viele davon).

3.Versuch:
Um eine saubere Lösung zur Compilierung von C-Dateien mit g++ zu finden, fand ich in der Dokumentation von qmake diesen Hinweis:
QMAKE_EXT_CPP - Causes qmake to interpret all files with these suffixes as C++ source files.
Also fügte ich in meine Projektdatei ein:
QMAKE_EXT_CPP = .c

Dies erschien zunächst auch nicht erfolgreich, denn build erzeugte die Fehlermeldungen
Warnung: Alte Befehle für das Ziel >>.c.o<< werden ignoriert
Warnung: Die Befehle für das Ziel >>.c.o<< werden überschrieben
Diese Warnungen waren mit dem Symbol für Fehler gekennzeichnet. Build erzeugte dennoch ein neues lauffähiges Programm.

Wenn ich von den Warnungen absehe, hätte ich zwei Lösungen. Doch die beiden Warnungen gefallen mir nicht.
Was meint ihr, kann ich ohne Gefahr von "Nebenwirkungen" auch die zweite Lösung wagen?

Verfasst: 21. November 2007 09:18
von solarix
Ich stellte fest, dass qmake ein Makefile so erzeugt, dass stets eine Datei *.c mit gcc und nicht g++ compiliert wird.
Meiner Meinung nach verhält sich hier qmake goldrichtig.. den C und C++ sind unterschiedliche Programmiersprachen (wie du bereits durch den Linkerfehler festgestellt hast)

Versuch 1 und Versuch 2 sind (aus obig genanntem Grund) Basteleien.. Da du die Header-Dateien nicht ändern möchtest, gehe ich davon aus, dass der Source nicht von dir ist (z.B. autogeneriert). Daher ist das Umbenennen auch nicht wirklich elegant..

Folgender Vorschlag (#4?):
Du änderst die Header-File des C-Codes nicht, erstellst jedoch eine saubere "Wrapper"-Header:

fname_cpp.h

Code: Alles auswählen

#ifndef _MY_WRAPPER_
#define _MY_WRAPPER_

#ifdef __cplusplus
extern "C"
{
#endif

#include "fname.h"

#ifdef __cplusplus
}
#endif

#endif
Diese Header kannst du nun ganz normal in beliebig viele C/C++-Sourcen einbinden, Und qmake kannst du machen lassen, was es will..

Weil du erwähnt hast, dass du viele Source-Dateien hast, würde ich in Erwägung ziehen, das ganze als C-Library (also ausserhalb deines Qt-Projektes) bereit zu stellen..