C-function in einem Constructor aufrufen

Alles rund um die Programmierung mit Qt
Antworten
qtNiko
Beiträge: 216
Registriert: 6. April 2007 21:26
Wohnort: München

C-function in einem Constructor aufrufen

Beitrag 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
Gruß von qtNiko

Core i5 760, GT 240, Suse Linux11.3, Eclipse-CDT-Helios, QT4.4, QT-Integration
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Beitrag 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...)
qtNiko
Beiträge: 216
Registriert: 6. April 2007 21:26
Wohnort: München

Beitrag von qtNiko »

nun, das Make-File wird von qmake erstellt. Da mache ich selber gar nichts dran.
Gruß von qtNiko

Core i5 760, GT 240, Suse Linux11.3, Eclipse-CDT-Helios, QT4.4, QT-Integration
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag 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...
kitov
Beiträge: 36
Registriert: 29. November 2006 12:24

Beitrag von kitov »

Das ist eine Fehlermeldung vom Linker , Bibliothek mit der Implementierung der Funkiton fehlt .
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag 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
kitov
Beiträge: 36
Registriert: 29. November 2006 12:24

Beitrag von kitov »

Du hast recht , sourcefile ist vorhanden , hab flasch geguckt :-)
qtNiko
Beiträge: 216
Registriert: 6. April 2007 21:26
Wohnort: München

Beitrag 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?
Gruß von qtNiko

Core i5 760, GT 240, Suse Linux11.3, Eclipse-CDT-Helios, QT4.4, QT-Integration
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag 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..
Antworten