PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : extern "C" + Class::Methode = Thread?



dml
06-09-2012, 07:22
Hi,

ich arbeite gerade mit C-Datenbankschnitstellen. Nun wollte ich QMainWindow (Qt\C++) anwenden und dabei habe ich herausgefunden das extern "C" in Methoden nicht funktioniert. Deshalb wollte ich jetzt mit einem Thread das Problem lösen. Vorteil für mich wäre, das ich die Threadtechnologie erstmals praktisch anwenden kann. Doch vorher wollte ich lieber noch einen erfahreren Programmierer fagen, was er von dieser Lösung hält?

Besten Dank!
dml

sommerfee
06-09-2012, 08:21
Nun wollte ich QMainWindow (Qt\C++) anwenden

Was genau meinst du mit "anwenden"? Eine Methode von QMainWindow aufrufen?


und dabei habe ich herausgefunden das extern "C" in Methoden nicht funktioniert.

Was genau meinst du mit "in Methoden nicht funktioniert"? Natürlich funktioniert extern "C" in Methoden. Oder meinst du vielleicht "für Methoden"? Dies könnte man einfach über eine Hilfsfunktion lösen, die eben ein QMainWindows* als ersten Parameter verlangt.


Deshalb wollte ich jetzt mit einem Thread das Problem lösen.

Wie soll ein Thread dieses Problem lösen?

dml
06-09-2012, 08:40
Als ich versucht habe in einer Methode mit extern "C" meinen c Quelltext einzufügen:


int MWindow::db_connect(){
extern "C"{
struct Datenbank datenbank;
db_laden(datenbank);
....
}
}

Habe ich die Fehlermeldung:


error: expected unqualified-id before string constant

erhalten. Nach Internatrecherche ist der Fehler darauf zurück zuführen, das man extern "C" nicht in Methoden anwenden kann.
Später sollen diese in C geschriebenen Funktionen bei Signalen von QMainWindow angewendet werden. Datei->Datenbank verbinden
Stimmt, Threads führen nicht zu einer Lösung des Problemes. Mit dem QtSql-Modul halte ich mich aber noch ein bisschen zurück.

anda_skoa
06-09-2012, 10:00
extern "C" ist eine Deklaration, sowas kommt nicht innerhalb einer Methodendefinition vor.

Vermutlich hast du diese Deklaration irgendwo in einem Header, also inkludierst du einfach diesen Header und rufst die Funktion ganz normal auf



#include "datenbankheader.h"

int MWindow::db_connect() {
struct Datenbank datenbank;
db_laden(datenbank);
....
}


Ein Thread ist nur ein zusätzlicher Laufzeitkontext, an der Übersetzung des Programms ändert das nichts.

Ciao,
_

dml
06-09-2012, 11:09
Hi,
erst einmal vielen Dank Euch beiden!
Die Klasse war von mir Selber entwickelt und es funktioniert nicht in einer Methode.
Da ich das Projekt aber auch gerne als C Referenz verwenden möchte, verwende ich jetzt einfach GTK und habe das lästige Problem einfach nicht mehr.

anda_skoa
06-09-2012, 13:42
Kannst du uns die entsprechende C Funktion zeigen?

Ich bin sehr verwundert dass eine C++ Funktion mit dem selben Inhalt nicht ebenso funktionieren würde.

Ciao,
_

dml
07-09-2012, 09:03
Hi,

Ich habe von früher noch eine kleine Testklasse, die ich für solche Versuche immer gerne verwende:

klasse.h


#ifndef KLASSE_H
#define KLASSE_H

#include <iostream>
using namespace std;


class Klasse
{
public:

int variable;
int i[3];

Klasse();
Klasse(int _fktvara, int _fktvarb); //Konstruktor
~Klasse(); //Destruktor
int Methode(int fktvara, int fktvarb);

};

#endif

klasse.cpp


#include "klasse.h"

// Konstruktor
Klasse::Klasse()
{
variable=Methode(1,2);
}

Klasse::Klasse(int _fktvara, int _fktvarb)
{
variable=Methode( _fktvara, _fktvarb);
}

// Destruktor
Klasse::~Klasse()
{
}


int Klasse::Methode(int fktvara, int fktvarb)
{
variable = fktvara + fktvarb;

cout<<"variable="<<variable<<endl;
cout<<"&variable="<<&variable<<endl;
// cout<<"&variable="<<this->&variable<<endl;
cout<<"&variable="<<&this->variable<<endl;
extern "C"{
printf("Hallo extern \"C\"!\n");
}
return variable;
}


int main()
{
int k;
Klasse Objekt;
cout<<"Objekt.variable="<<Objekt.variable;
k = Objekt.Methode(4,5);
cout<<"Rückgabewert von Objekt.Methode="<<k;

return 0;
}

main.cpp


#include "klasse.h"

#include <iostream>
using namespace std;

int main()
{
int k;
Klasse Objekt();
// cout<<"Objekt.variable="<<Objekt.variable;
// k = Objekt.Methode(4,5);
// cout<<"Rückgabewert von Objekt.Methode="<<k;

return 0;
}


Auch hier erhalte ich bei extern "C" die Fehlermeldung:


error: expected unqualified-id before string constant

anda_skoa
07-09-2012, 10:09
Auch hier erhalte ich bei extern "C" die Fehlermeldung:

Ja, weil du


extern "C"

In einer Funktion stehen hast und das dort nicht verloren hat.

Korrekt lautet deine Funktion so


#include <stdio.h>

int Klasse::Methode(int fktvara, int fktvarb)
{
variable = fktvara + fktvarb;

cout<<"variable="<<variable<<endl;
cout<<"&variable="<<&variable<<endl;
// cout<<"&variable="<<this->&variable<<endl;
cout<<"&variable="<<&this->variable<<endl;
printf("Hallo extern \"C\"!\n");
return variable;
}




Ciao,
_

dml
07-09-2012, 10:57
Ja, aber auch nur weil C++ die Funktion printf kennt. Doch wenn ich dort spezifischeren c Quelltext einfüge, würde es wieder nicht funktionieren.

sommerfee
07-09-2012, 12:33
Ja, aber auch nur weil C++ die Funktion printf kennt. Doch wenn ich dort spezifischeren c Quelltext einfüge, würde es wieder nicht funktionieren.

Den kannst du doch mit "extern "C"" vorab deklarieren, so daß der Linker die Funktion(en) auch später findet. Genau dafür ist doch "extern "C"" da.

(Und bei printf() wird es auch genau so gemacht, schaue doch einfach 'mal in die stdio.h-Datei rein.)

anda_skoa
07-09-2012, 15:00
Ja, aber auch nur weil C++ die Funktion printf kennt. Doch wenn ich dort spezifischeren c Quelltext einfüge, würde es wieder nicht funktionieren.

Das funktioniert mit jeder C Funktion.
Wie in C selbst muss die Deklaration der Funktion entweder in der Datei selbst oder über ein Include eines Headers bekannt gemacht worden sein.

Am Aufruf der Funktion ändert sich nichts, wie man am Beispiel von printf() sehr einfach zeigen kann.

Der bei dir aufgetretene Fehler hat nichts damit zu tun, dass die aufgerufene Funktion in C und der aufrufende Code in C++ geschrieben sind.

Auch in einer C Funktion hätte das zu einem Fehler geführt, bzw. würde ein Aufruf, der in einer solchen Funktion kompiliert, auch in einer C++ Funktion kompilieren.

Dass in deinem Fall die C++ Funktion die Methode einer Klasse ist, ändert an der Situation auch nichts.

Ciao,
_

dml
07-09-2012, 16:03
Hi,
nachdem ich das getan habe, was ich schon hätte tun sollen bevor ich Euch nervte, (im Buch nachschlagen) habe ich meinen Fehler erkannt. extern "C" {} ist für Funktionen die in C geschrieben sind da, nicht um einfach c-Quelltext reinzukloppen. Deshalb war, das was ich in der Methode getan habe totaler Quatsch.

Vielen Dank Euch beiden und schönes Wochenende!


P.S.:
Merk schon Ihr Beide wollt mich von meiner ersten C Referenz abbringen. Doch verhält es sich damit, wie mit dem Picasso Gemälde an der Wand. Was stört es dem Besitzer das es nicht Echt ist, solange er es nicht weiß. ;)