vector an dll übergeben
-
Hi Leute,
Hab doch noch ne Lösung gefunden, mit der ich wenigstens einen vector als Rückgabewert aus einer DLL bekommen und wollt hier noch meine Lösung posten:die DLL:
//die Funktion, die den vector zurückgeben soll: __declspec(dllexport) std::vector<std::string>* GetVector() { std::vector<std::string> *m = new std::vector<std::string>; //Den vector füllen for(int i = 0; i < iWasauchImmer; i++) { m->push_back("Der Text"); } }
die .exe oder auch eine andere DLL, die die DLL benötigt:
__declspec(dllimport) std::vector<std::string>* GetVector(); //Dann irgendwo der Aufruf std::vector<std::string> *v = GetVector();
Und schon hab ich den gefüllten vector aus der DLL
Hoffe das hilft vielleicht dem ein oder anderen, da ich selber schon Tagelang auf der Suche nach so einer Lösung war auch wenn sie im Endeffekt einfacher war als gedacht.mfg mached
-
Und wie löschst du den vector?
-
Meinst du den Speicher wieder freigeben, oder einzelne Einträge des vectors zu löschen.
Bzgl. der Speicherfreigabe: Soweit ich weiß muss man sich bei vectoren um den Speicher nicht kümmeren, da der vector eine dynamische Speicherverwaltung hat. Ansonsten geb ich sowieso den kompletten Speicher der DLL wieder frei, sobald ich sie nicht mehr brauche (ich binde diese dynamisch)mfg mached
-
Nö, das meine ich nicht.
Du rufst in deinem Code new auf. Wo ist das dazugehörige delete?
-
Ich glaub das Problem kannst du auch dadurch lösen, wenn du die Multithreaded Standardlibrary anstatt der Singlethreaded nimmst.
-
Das delete fehlt an dieser Stelle daher, dass ich den vector ja als Rückgabewert habe. Wenn ich delete jetzt noch in der DLL ausführen würde, hätte ich ja in der .exe keine Werte mehr bzw. das ganze würde irgendwo ins leere führen.
Ansonsten wird der Speicher, den der vector sich geholt hat im dekonstruktor vom vector selbst wieder freigegeben. Soll angeblich so sein
Deswegen geb ich noch den kompletten Speicher der DLL vorsichtshalber dann frei, wenn die DLL selbst wieder frei gegeben wird.
Das einzige was man noch machen kann wäre in der .exe:
delete[] v;
funktioniert soweit auch, nur konnte ich bisher noch nicht nachprüfen ob wirklich der Speicher des vectors freigegeben wird.mfg mached
P.S.: gefunden hab ich das ganze hier: http://support.microsoft.com/default.aspx?scid=kb;en-us;172396
-
Du hast mich anscheinend nicht richtig verstanden.
Speicher, der mit new in der DLL angefordert wurde, muss auch in derselben DLL wieder freigegeben werden. Sonst bewegst du dich auf sehr sehr dünnem Eis. Den Speicher nicht freizugeben ist keine ernstzunehmende Lösung.So blöd es sein mag, die DLL muss also eine Funktion bereitstellen, die nichts anderes als "delete v;" macht. (delete**[]** v war hoffentlich nur ein Schreibfehler deinerseits.)
-
Also verstanden hatte ich dich schon richtig, aber ich wusste nicht genau, ob der vector den Speicher von alleine wieder freigibt, aber diese Frage hast du mir damit beantwortet, danke.
Wegen der Funktion, die den Speicher wieder freigibt, da hatte ich ja schon geschrieben, dass ich den Speicher wieder freigebe, wenn die DLL an sich wieder frei gegeben wird.(Ich brauch die immer nur kurz) Und man bekommt ja einige Messages, wie z.B. DLL_THREAD_DETACH, DLL_PROCESS_DETACH,... und in
denen geb ich den Speicher wieder frei, auch den des vectors. Es sei denn, es gibt noch andere Möglichkeiten, die Auftreten können, so dass eine Funktion zur Speicherfreigabe sinnvoller wäre.
Das delete[] war wirklich ein Tipp- bzw. Gedankenfehler, sorry.
Ansonsten vielen Dank für die Hinweise, mir ist dadurch der Umgang mit vectoren um einiges klarer geweorden.mfg mached
-
Bei meisten (ich kenn keinen bei dem dies nicht der fall ist!) Win32 Compiler werden new und delete mit Hilfe der HeapAlloc Funktionen aus der Kernel32.dll implementiert. Um diese aber benutzen zu können muss man aber ein Heap mit HeapCreate erschaffen dies geschiet im Start-up Module. Das Problem ist aber, dass die dll und exe 2 Start-up Modules haben und somit zwei Heaps und wenn du versuchst ein Wert im Heap 1 durch aufrufen von HeapFree für Heap 2 freizugeben macht es bum.
Desweiteren ist ein Heap Handle Processlokal, das heist selbst wenn du den Handle bekommen solltest und ihn an die exe übergeben würdest, würde es nicht klappen.
Eine Lösung ist das benutzen von CreateFileMapping oder du machst was ich in solchen Fällen mache. Du packst einfach diese Funktion in die dll:
void free_vector_int(vector<int>*a) { delete a; }
Für jeden Class Pointer musst du eine free Funktion schreiben wegen des Destructors. Ach und vector<int> ist eine andere Class als vector<char>!
-
Irgendwer schrieb:
Bei meisten (ich kenn keinen bei dem dies nicht der fall ist!) Win32 Compiler werden new und delete mit Hilfe der HeapAlloc Funktionen aus der Kernel32.dll implementiert. Um diese aber benutzen zu können muss man aber ein Heap mit HeapCreate erschaffen dies geschiet im Start-up Module. Das Problem ist aber, dass die dll und exe 2 Start-up Modules haben und somit zwei Heaps und wenn du versuchst ein Wert im Heap 1 durch aufrufen von HeapFree für Heap 2 freizugeben macht es bum.
Was hab ich denn geschrieben?
Irgendwer schrieb:
Desweiteren ist ein Heap Handle Processlokal, das heist selbst wenn du den Handle bekommen solltest und ihn an die exe übergeben würdest, würde es nicht klappen.
Bin mir da gerade nicht 100% sicher, aber können DLL und EXE nicht die gleichen Handles benutzen?
Das sind ja keine zwei Prozesse.Irgendwer schrieb:
Eine Lösung ist das benutzen von CreateFileMapping oder du machst was ich in solchen Fällen mache. Du packst einfach diese Funktion in die dll:
void free_vector_int(vector<int>*a) { delete a; }
Für jeden Class Pointer musst du eine free Funktion schreiben wegen des Destructors.
Was hab ich denn geschrieben?