PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : probleme c+ code



Tuxist
01-02-2007, 18:52
Moin,
Versuche gerade eine cms mit c++ zu schreiben versuche jetzt funktionen in shared libary's zu schreibe, dies ist für mich neuland.

Mein c++ code

index.cpp


#include <iostream>
#include <string>
#include <fstream>
#include "index.h"
#include <dlfcn.h>
#include "lib/libcss/include/css.h"

using namespace std;


int main()
{

dlopen("lib/libcss/libcss.so", RTLD_LAZY);

cout << "Content-type: text/html" << endl
<< "<html>" << endl
<< "<head>" << endl
<< "<title>Wikommen auf Tuxist Mainbase</title>" << endl
<< "</head>" << endl;

cout << cssheader;

cout << "<body>" << endl
<< "<h1><em>" << endl
<< "Im Aufbau" << endl
<< "</em></h1>" << endl
<< "</body>" << endl
<< "</html>";
}


css.cpp



[/CODE#include <iostream>
#include <fstream>
#include <string>

using namespace std;

class libcssread
{
public:
char cssheader;
ifstream cssread;
string csspath;
};

int main()
{
char cssheader;
ifstream cssread;
string csspath;

cssread.open(csspath.c_str());
while (cssread.eof() !=true)
{
cssheader = cssread.get();
cssread.close();
}

}
]



css.h (css header)


class libcssread
{
public:
char cssheader;
ifstream cssread;
string csspath;
};



g++ output


make
/usr/bin/gcc -Wall -fsigned-char -Ilib/libcss/include -Llib/libcss index.cpp
lib/libcss/include/css.h:5: error: ‘ifstream’ does not name a type
lib/libcss/include/css.h:6: error: ‘string’ does not name a type
index.cpp: In function ‘int main()’:
index.cpp:22: error: ‘cssheader’ was not declared in this scope
make: *** [all] Fehler 1

TheHawk
01-02-2007, 20:05
Die Typen ifstream und string, welche in der css.h verwendet werden, gibt es nicht. Und die Variable cssheader in der index.cpp wurde in der Funktion main() nicht deklariert.

Tuxist
01-02-2007, 20:34
so die type fstream und string wurden mit #include <fstream> und # <string> bennant.
Und libcssread wurde alls klasse in css.h bennant und css.cpp verarbeitet.
Daher frage ich mich ?
css.h muss eigentlich kein #include stehen oder ?
warum kann von der klasse einzelne funtionen in der int main() nicht verwenden ?
Denn css.h dien leglich als api header für die libcss.

panzi
02-02-2007, 14:44
so die type fstream und string wurden mit #include <fstream> und # <string> bennant.
Und libcssread wurde alls klasse in css.h bennant und css.cpp verarbeitet.
Daher frage ich mich ?
css.h muss eigentlich kein #include stehen oder ?
warum kann von der klasse einzelne funtionen in der int main() nicht verwenden ?
Denn css.h dien leglich als api header für die libcss.
Das hier ist C++, nix hihglevel artiges wie Java. Jeder der mit einen Objekt was macht, muss es kennen. Kennen tut er es nur wenn er Deklarationen dazu hat. Jeder, der's verwendet, muss die .h file includieren, sonst kennt ers net.

Und was machst mit dem dlopen? Da öffnest eine shared lib. und vergisst den handel drauf gleich wieder? Und dlopen ist für C geschrieben, nicht C++. D.h. du musst um C++ Funktionen extrahieren zu können entweder den gemangelten Namen wissen oder die Funktion als extern "C" deklarieren. dlopen ist wohl nur für plugins gut, ansonsten gibt's IMHO keinen Grund das in C++ zu verwenden.

Zur Verwendung von dlopen siehe:
http://www.die.net/doc/linux/man/man3/dlopen.3.html

anda_skoa
02-02-2007, 20:07
so die type fstream und string wurden mit #include <fstream> und # <string> bennant.


In css.cpp und dort ist die Deklaration der Variablen auch erst nach dem

using namespace std

sonst gäbe es dort auch ein Problem.

Du kannst das in index.cpp auch machen, wenn du vor dem include von css.h den Namespace öffnest.

Normalerweise wird das include für direkte Instanzen, also wenn es keine Pointer oder Referenzen sind, direkt in der Header Datei gemacht, die die Deklaration enthält, in deinem Falle also css.h



Und libcssread wurde alls klasse in css.h bennant und css.cpp verarbeitet.

Der Compiler hat dort auch keinen Fehler gemeldet, sondern in index.cpp

css.cpp kann vermutlich einwandfrei kompiliert werden.



Daher frage ich mich ?
css.h mus
s eigentlich kein #include stehen oder ?

Korrekt, müssen nicht. Meistens macht man das, damit man diese includes nicht in jeder Datei wiederholen muß, die den Header (in deinem Fall css.h) inkludiert.

Aber wie oben gesagt kannst du alternativ vor dem inkludieren von css.h alle dort verwendeten Typen auch direkt in index.cpp inkludieren und entweder die Namespaces mit angeben oder die Namespaces öffnen.

Raten würde ich aber eher dazu, diese Typen gleich in css.h zu erledigen, d.h. in etwas so



#include <fstream>
#include <string>

class libcssread
{
public:
char cssheader;
std::ifstream cssread;
std::string csspath;
};

(Natürlich die Include Guards nicht vergessen)



warum kann von der klasse einzelne funtionen in der int main() nicht verwenden ?


Deine Klasse hat erstens keine Funktionen, sondern nur Daten, und du hast in der main Funktion in index.cpp keine Instanz dieser Klasse.

Etwas nicht vorhandenes kann nicht benutzt werden, ist in der Relalität meistens auch so ;)



Denn css.h dien leglich als api header für die libcss.
Ja, das ist auch ok.

Was neben dem unverständlichen dlopen() Aufruf, den panzi schon behandelt hat, noch aufgefallen ist, ist daß du zwei mal int main() definiert hast, was auf keine Fall linken wird.

Außerdem sieht der Compiler Aufruf nicht korrekt aus, dort ist gcc statt g++ zu sehen, was zwar den C++ Code noch einwandfrei kompilieren wird, aber im Linker Schritt nicht die C++ Standardbibliothek mit nimmt und daher mit einem Fehler abbrechen wird.

Ciao,
_

Tuxist
03-02-2007, 12:42
danke deine Antwort hat mir sehr geholfen :)

habe jetzt einiges geändert:
css.cpp


#include <iostream>
#include <fstream>
#include <string>

using namespace std;

void libcssread(void)
{
char cssheader;
ifstream cssread;
string csspath;

cssread.open(csspath.c_str());
while (cssread.eof() !=true)
{
cssheader = cssread.get();
cssread.close();
}

}


css.h


#include <fstream>
#include <string>

using namespace std;

void libcssread(void)
{
char cssheader;
std::ifstream cssread;
std::string csspath;
};


index.cpp


#include <iostream>
#include "index.h"
#include <dlfcn.h>

using namespace std;

#include "lib/libcss/include/css.h"

int main()
{

cout << "Content-type: text/html" << endl
<< "<html>" << endl
<< "<head>" << endl
<< "<title>Wikommen auf Tuxist Mainbase</title>" << endl
<< "</head>" << endl;

libcssread();

cout << "<body>" << endl
<< "<h1><em>" << endl
<< "Im Aufbau" << endl
<< "</em></h1>" << endl
<< "</body>" << endl
<< "</html>";
}



g++ output:


/usr/bin/g++ -Wall -fsigned-char -Ilib/libcss/include -Lbin/lib/libcss -llibcss index.cpp
lib/libcss/include/css.h: In function ‘void libcssread()’:
lib/libcss/include/css.h:8: warning: unused variable ‘cssheader’
/usr/bin/ld: cannot find -llibcss
collect2: ld returned 1 exit status
make: *** [all] Fehler 1


makefile index.cpp


CXX= /usr/bin/g++
CXXOPTFLAGS=
CXXFLAGS=$(CXXOPTFLAGS) -Wall -fsigned-char -Ilib/libcss/include -Lbin/lib/libcss -llibcss

lib_SRC= \
index.cpp

all:
$(CXX) $(CXXFLAGS) $(lib_SRC)

anda_skoa
03-02-2007, 14:59
Sehr fein.

Ein paar weitere Anmerkungen:

libcssread() ist jetzt eine Funktion. Eine Funktion brauchst du im Header lediglich zu deklarieren, sie sollte keinen Body (Implementierung) haben, wenn du diese Implementierung auch noch in einer anderen Datei hast.

Das führt nämlich dazu, daß die Funktion zweimal vorhanden ist und dann der Linker auch wieder ein Problem hat.

In css.h reicht jetzt das



void libcssread();


Am besten du benutzt css.h auch in css.cpp, dann hast du schon beim Erstellen der Bibliothek diese Doppeldeutigkeit als Fehler und siehst sie nicht erst bei einem Programm, das die Bibliothek benutzt.

Allerdings gehe ich davon aus, daß die mit den Daten auch noch was machen willst, im Moment, sind sie nur während der Abarbeitung von libcssread() gültig und die hat keinen Rückgabewert oder Ausgabeparameter.

Dein aktueller Linkerfehler sagt, daß die Bibliothek liblibcss.a bzw. liblibcss.so nicht gefunden wurde.
Vermutlich heißt deine Bibliothek libcss, daher ist bei der Linkerangabe nur das hier nötig


-lcss

Das liegt daran, daß der Basisname einer Bibliothek über Plattformen hinweg gleich ist, aber der tatsächliche Dateiname anders aussehen kann.

zB wird eine statische Bibliothek mit dem Basisnamen "css" unter Unix "libcss.a" heißen, unter Windows würde sie "css.lib" heißen.

Ciao,
_

P.S.: noch etwas zu Namespaces


#include <string>

using namespace std;

std::string foo;

Ist doppelt gemoppelt :)

In einem Header schreibt man eher so


#include <string>

std::string foo;

Damit man dem Benutzer des Headers nicht dazu zwingt, den gesamten Namespace "std" geöffnet zu haben.

In einer Quelldatei ist es meist Geschmackssache, als Mittelweg macht man dort meistens das hier


#include <string>

using std::string;

string foo;

Tuxist
03-02-2007, 15:56
danke schön