Programm mit DLL weitergeben
-
POD - plain old data
Das sind all die alten Datentypen die man auch so aus C kennt (int, float, char, char*).Versuche die dll so stark wie möglich zu kapseln und alle Übergaben eben mit PODs machen. Dann mußt du statt TStringList halt etwas wie char** nehmen. Du kannst solche Sachen ja in eigenen Klassen kapseln damit das Handling einfacher wird.
Ich sage jetzt nicht, dass dein Fehler damit was zu tun hat, dazu weiß ich zu wenig.
Sind bei dir irgendwelche Threads im Spiel? Besteht die Möglichkeit, dass einer der übergebenen Pointer ungültig wird (durch das Hauptprogramm) bevor die in der Dll liegende Funktion fertig abgearbeitet ist? Hast du die MEMMGR.LIB zu deinem Dll-Projekt hinzugefügt?
-
nein threads sind nicht im spiel!
mem....lib ist überall drin und auch die brlndmm.dll ist mit dabei!der fehler tritt nicht mehr auf, wenn ich das
delete VDAList;weglasse!
aber wieso?
da ich ja danach direkt wieder speicher anfordere mit
VDAList = new TStringList();was ist daran falsch?
-
wie könnte ich eine klasse gut implementieren? in die dll?
im hauptprogramm?und wie kann ich eine gute schnittstelle für zB TStringList schreiben?
(wollte ja eigentlich die manuelle speicherverwaltung mit vector und Stringlist umgehen)
-
und auch bei einem CLear() bekomme ich eine AccessViolation!
Kann ich denn ein delete oder Clear() vor dem neuen Laden aus einer Datei einfach weglassen?
-
Wo rufst du denn dein delete auf. Du mußt noch wissen, das Instanzen die mit new erstellt worden sind, immer in derselben Übersetzungseinheit (ist hier vielleicht nicht das richtige Wort) wieder gelöscht werden müssen. D.h. was du in der dll mit new erstellst, mußt du auch in der dll wieder löschen. Wenn du es im Hauptprogramm lösche willst, mußt du eine Löschfunktion in die dll einbauen und dann exportieren.
Für Stringexporte habe ich mir eine eigen kleine Klasse geschrieben, die nichts weiter hat als die großen 3 (für die Klasse und für const char*) sowie eine c_str() für Rückkonvertierungen. Als Ersatz für TStringList könnte man dann ein Array davon nehmen. Man braucht das ja nur für die Übergabe, intern kann man ja wieder mit den gewohnten Klassen Arbeiten.// LightString.h: Einfache Stringklasse (für dlls) // ////////////////////////////////////////////////////////////////////// #if !defined(LightString_H_) #define LightString_H_ #include <algorithm> class LightString { private: void Swap(LightString& src) { std::swap(buf, src.buf); std::swap(used, src.used); } public: LightString() : buf(0), used(0) { } LightString(const char* src) : buf(0), used(0) { if( src != 0) { size_t newlen = strlen(src); try { buf = new char[newlen+1]; std::copy(src, src + newlen, buf); buf[newlen] = '\0'; used = newlen+1; } catch(...) { buf = 0; used = 0; } } } ~LightString() { delete[] buf; } size_t size() { return used-1; } LightString(const LightString& src) : buf(src.used > 0 ? new char[src.used] : 0), used(src.used) { if( src.used > 0 ) std::copy(src.buf, src.buf + src.used, buf); } LightString& operator=(const LightString& src) { if( this != &src) { LightString temp(src); Swap(temp); } return *this; } LightString& operator=(const char* src) { LightString temp(src); Swap( temp ); return *this; } const char* c_str() const { if( used > 0 ) return buf; return ""; } void clear() { delete[] buf; buf = 0; used = 0; } private: char* buf; size_t used; };
-
also deklaration imn header
TStringList* VDAList;speicher holen im konstruktor der form
VDAList = new TStringList;speicher freigeben hab ich an mehreren stellen versucht (destruktor der form, direkt nach beendigung der arbeit mit der liste...alles mögliche)
ich verstehe es nicht!
diese TStringList ist die einzigste die wirklich nur Hauptprogramm verwendet wird (in den DLLs nur um sachen zu lesen, nicht schreiben)
und wenn ich vor dem laden aus der datei ein Clear() oder delete mache (danach natürlich wieder speicher holen), und dann das LoadFromFile() ein 2tes mal ausführe, bekomm ich die AccessViolation, lasse ich das delete oder Clear() weg, geht es erstmal (bekomme dann später eine AccessViolation)
worann kann es denn noch liegen?
-
ahh es liegt wohl doch wo anders dran, und zwar wirklich beim löschen eines vectors mit einer funktion aus der dll
//vector füllen __declspec(dllexport)void FillVectorList(TStringList* List,std::vector<TStringList* >& listVector, std::vector<int>& iVec, std::vector<std::pair<int,int> >& pVec) { TStringList* seperateList; int vstart, vstop; for(int i = 0; i < iVec.size(); ++i) { vstart = pVec.at(i).first; vstop = pVec.at(i).second; if(i == iVec.size()-1) vstop = pVec.at(i).second - 1; seperateList = new TStringList(); for(int i = vstart; i <= vstop; ++i) seperateList->Add(List->Strings[i]); listVector.push_back(seperateList); } } //vector wieder löschen __declspec(dllexport)void DeleteVectorList(std::vector<TStringList*>& listVector) { std::vector<TStringList*>::iterator it; it = listVector.begin(); for(it; it != listVector.end(); ++it) delete *it; listVector.clear(); }fehler tritt nur auf, wenn davor das ausgeführt wurde (im Hauptprogramm)
DeleteVectorList(vList);wo ist also in der funktion der fehler?
oder sollte ich diese funktion lieber im hauptprogramm schreiben?
-
Du mußt sicherstellen, dass die TStringList-Objekte ausschließlich in der dll erzeugt und gelöscht werden. Auch solltest du in der dll erzeugt StringListinstanzen nicht im Hauptprogramm ändern. Lieber erstmal kopieren.
Am besten machst du das, indem du bei der Schnittstelle immer konstante Referenzen übergibst. Warum eigentlich diese Vermengung von STL und VCL? Tut es hier ein vector<vector<string> > nicht auch?
-
würde es hier etwas bringen, wenn ich es so mache?
DLL__declspec(dllexport)void DeleteVectorList(std::vector<TStringList*>& listVector) { std::vector<TStringList*>::iterator it; it = listVector.begin(); for(it; it != listVector.end(); ++it) delete *it; listVector.clear(); } __declspec(dllexport)void FillVectorList(TStringList* List,std::vector<TStringList* >& listVector, std::vector<int>& iVec, std::vector<std::pair<int,int> >& pVec) { TStringList* seperateList; int vstart, vstop; DeleteVectorList(listVector); //hier das bereinigen des vectors for(int i = 0; i < iVec.size(); ++i) { vstart = pVec.at(i).first; vstop = pVec.at(i).second; if(i == iVec.size()-1) vstop = pVec.at(i).second - 1; seperateList = new TStringList(); for(int i = vstart; i <= vstop; ++i) seperateList->Add(List->Strings[i]); listVector.push_back(seperateList); } }
-
Die Funktionen sind soweit in Ordnung. Wie werden sie denn im Hauptprogramm verwendet? Ich denke da liegt dann der Fehler. Wenn es zu viel wird, kannst du mir das projekt ja mal schicken.
-
naja sooo viel ist es nicht, aber relativ unübersichtlich, weil es noch so eine art test-entwicklung ist!
ich schicke es dir mal, wenn du was nicht verstehst, kannst gerne fragen!
-
@braunstein:
hm...hab mich gerade angemeldet, bekomme aber meine mail net zum aktivieren!
kannst du deine adresse mal hier reinschrieben?oder hast ICQ?
dann kannst mir die nummer an seb_schneider (at) gmx (punkt) de schicken!
-
könnte mir viell CodeGuard helfen?
wenn ja wie?
habe es in den prjekt optionen aktiviert, und das DebugFenster geöffnet, allerdings wird nie etwas angezeigt...