"Dynamische" DLL - "run-time-dll" Win32.dll
-
Hallo liebe C++ Gemeinde...
Ich erarbeite mir gerade das einbinden von DLL´s in meinen Projecten. Dabei bin ich auf ein kleines Problem gestoßen, welches ich auch lösen konnte. Nur gefällt mir die Lösung so nicht ganz und ich wollte mal sehen ob vielleicht hier im Forum mir jemand einen Denkanstoß geben kann wie ich es noch lösen könnte.
Wichtig ist das einbinden der DLL´s soll bzw muss dynamisch erfolgen, so das bis auf die .DLL und den Header nichts weiter benötigt wird (also keine .lib Datei)
Das Problem ist nun folgendes. Ich hab Klassen mit mehreren Funktionen unter anderem auch "static" Funktionen. Die also benutzbar bleiben müssen ohne ein Object davon zu erstellen.
Um in der Anwendungen folgenden zugriff zu erhalten : Beispiel :
wxString erg = Vers::AusZweiMachEins(_T("Teil_1"), _T("Teil_2")); // HIER ERSTER AUFRUF wxMessageBox(erg); static const wxChar* LIB_NAME = _T("vers"); static const wxChar* FUNK_NAME = _T("GetNewClass"); wxDynamicLibrary* dllHandle = new wxDynamicLibrary(); dllHandle->Load(LIB_NAME); Vers* PointerToClass = 0; if (!dllHandle->IsLoaded()) { wxMessageBox(_T("Kann DLL nicht laden")); } else { wxMessageBox(_T("DLL geladen")); typedef Vers* (*fpFunc)(); if (dllHandle->HasSymbol(FUNK_NAME)) { wxMessageBox(_T("Funktion geladen")); fpFunc theFunk = static_cast<fpFunc>(dllHandle->GetSymbol(FUNK_NAME)); PointerToClass = theFunk(); erg = PointerToClass->AusZweiMachEins(_T("Teil_1"), _T("Teil_2")); // HIER ZWEITER AUFRUF wxMessageBox(erg); } else { wxMessageBox(_T("Funktion konnte nicht geladen werden.")); } } dllHandle->Unload(); delete dllHandle; delete PointerToClass;
Bevor ich jetzt mein Anliegen weiter erkläre gebe ich zeige ich erstmal den Quelltext der als .dll compilierten Headerdatei :
#ifndef __vers__ #define __vers__ // Header #include <iostream> #include <stdio.h> #include <windows.h> #include <wx/wx.h> #ifdef __staticLib_ #define DLLTYPE #define AllVirtual #define MustVirtual virtual #else // __staticLib_ #define AllVirtual virtual #define MustVirtual virtual #define DLLTYPE extern "C" __declspec(dllexport) #endif // __staticLib__ class Vers { wxString txt; public: Vers(); AllVirtual void SetText(const wxString& newTxt); AllVirtual wxString GetText() const; static wxString AusZweiMachEins(const wxString& a, const wxString& b) { wxString zusammen; zusammen << a << b; return zusammen; } }; #if (!defined(__staticLib_)) DLLTYPE Vers* GetNewClass(); #endif // (!defined(__staticLib_)) #endif // __vers__
Und natürlich die .cpp Datei :
// weitere Header #include "stdafx.h" #define MAXMODULE 500 #define __dll__ //#define __staticLib_ #include "vers.h" Vers::Vers() { } void Vers::SetText(const wxString& newTxt) { txt = newTxt; } wxString Vers::GetText() const { return txt; } #if (!defined(__staticLib_)) DLLTYPE Vers* GetNewClass() { return (new Vers); } #endif // (!defined(__staticLib_))
Das was mir bei dieser Implementierung nicht passt ist, das ich die Deklaration der Static-Funktion (wxString AusZweiMachEins()) im Header vornehmen muss und diese nicht in die entsprechende .cpp Datei auslagern kann.
Das Problem ist wenn ich dies tue, dann erhalte ich vom Linker einen nicht aufgelösten Verweis. Sowohl für den ersten als auch für den zweiten Aufruf der Funktion.
Selbst wenn ich die dazu erstellte LIB Datei include, ist es nicht möglich auf diese Funktion zuzugreifen.Ich weiß natürlich das ich Funktionen anfügen könnte wie, die es mir dann ermöglichen auf die Static-Funktion zuzugreifen. (Natürlich klar das ich wxString nicht verwenden kann, und diesen C-Conform machen muss, hier nur Bsp) Wie folgt :
#if (!defined(__staticLib_)) DLLTYPE Vers* GetNewClass() { return (new Vers); } DLLTYPE wxString HierKommIchZusammen(const wxString& a, const wxString& b) { // toDOhier zusammenführen bzw die static-Funktion aufrufen } #endif // (!defined(__staticLib_))
Aber dann würde ich es lieber bei meiner Lösung lassen, weil es mir zu “wild” erscheint immer den gesamten Prozess zum laden der Funktion wie im ersten Quelltext oben durchzuführen.
Hoffe ich habe mein Anliegen jetzt soweit einigermaßen gut erklärt. Bin mal gespannt auf Anregungen.
Grüße und erfolgreiches proggen
Ollow
-
statt
[code]
:static const wxChar* LIB_NAME = _T("vers"); static const wxChar* FUNK_NAME = _T("GetNewClass"); wxDynamicLibrary* dllHandle = new wxDynamicLibrary()
lieber
[cpp]
:static const wxChar* LIB_NAME = _T("vers"); static const wxChar* FUNK_NAME = _T("GetNewClass"); wxDynamicLibrary* dllHandle = new wxDynamicLibrary()
dann gibts bunte Farben und alles ist hübscher und besser lesbar
-
Jap sollte man. Irgendwie verpeilt. Aber habs gleich mal geändert
-
Okay
Static Funktionen inlinen und den Code dazu in einer seperaten .cpp ablegen welche ich mittels
#include"xyz.cpp"
ins Project hole...
Und schon macht das die ganze Sache etwas formschöner, weil ich dadurch "saubere" Header bekomme..