Laden von dll



  • Hallo,

    ich habe mir eine schöne dll in C++ geschrieben und die auch schon in einer win32 Konsolenanwendung benutzt. Nun wollte ich es mir ein wenig bequemer machen und das Projekt nochmal ein einer WinForm-Anwendung unter .NET realisieren. Hier schaff ich es aber nicht die dll einzubinden.
    Die im C++ Projekt verwendete Variante

    extern "C" __declspec(dllimport)void float3DFeldLaden(char* Dateiname, float ***feld, int dim1Max, int dim1Bis, int dim2Max, int dim2Bis, int dim3Max, int dim3Bis);
    

    funktioniert nicht. Nun bin ich nach ein bißchen Googlen auf folgende Variante gestoßen:

    extern "C" {
    	using namespace System::Runtime::InteropServices;
    	[DllImport("UTzeusPAFeld.dll", EntryPoint = "float3DFeldLaden")]
    	void float3DFeldLaden(char* Dateiname, float ***feld, int dim1Max, int dim1Bis, int dim2Max, int dim2Bis, int dim3Max, int dim3Bis);
    }
    

    Das Projekt lässt sich nun zwar anstandslos kompillieren, aber wenn ich dann zu dem Aufruf

    float3DFeldLaden(dateinameZiel3DFeldBinaer, zwischenSpeicher, 201, 201, 201, 201, 400, 400);
    

    komme, heißt es:

    Eine nicht behandelte Ausnahme des Typs "System.DllNotFoundException" ist in ZeusSimAuswertungWinForm.exe aufgetreten.

    Zusätzliche Informationen: Die DLL "UTzeusPAFeld.dll": Das angegebene Modul wurde nicht gefunden. (Ausnahme von HRESULT: 0x8007007E) kann nicht geladen werden.

    Das klingt sehr danach, dass die entsprechende dll nicht gefunden wird. Um sicher zu gehen hab ich sie mal in jeden relevanten Ordner, inklusive dem system32 von Windows, eingefügt - ohne Erfolg.

    Kann mir hier jemand sagen, was ich falsch mache?



  • Warum bindest Du die DLL nicht einfach *genau gleich* ein, wie Du es schon bei der "einfachen, unmanaged" Konsolen-Anwendung getan hast?
    Du bist hier bei C++/CLI und nicht bei C#; d.h. Du kannst _ganz normal_ C/C++ verwenden! (include/libs, usw).



  • Wie darf ich dich mit "genau gleich" verstehen? In der Konsolen-Anwendung hab ich die Funktionen der dll mit

    extern "C" __declspec(dllimport)void float3DFeldLaden(char* Dateiname, float ***feld, ...);
    

    eingebunden, und konnte sie problemlos nutzen. Mach ich das aber bei dem WinForm, dann erhalte ich einen Linker Fehler.



  • Dann hast Du halt vergessen, dass Du auch noch die LIB angegeben hast (entweder in der Projekteinstellungen oder via #pragma comment(lib, "name-der.lib"))

    Schau eunfach mal nach und mach es *genau gleich*... dann geht es 😉



  • Hab es "genau gleich" getan und ich hab immer noch kein Erfolg 😞
    Unter Projekt->Eigenschaften->Konfigurationseinstellungen->Linker->Eingabe hab ich die lib eingefügt (währrend ich bei der Konsolananweisung dran gedacht hatte, fehlte es hier tatsächlich), aber die Fehlermeldung ist die selbe geblieben. Der Vollständigkeit halber führ ich sie hier mal auf:

    Warnung 1 warning C4272: "float3DFeldLaden": Ist als __declspec(dllimport) markiert. Beim Importieren einer Funktion muss eine systemeigene Aufrufkonvention angegeben werden. c:\dokumente und einstellungen\skuemmri\eigene dateien\visual studio 2008\projects\zeussimauswertungwinform\zeussimauswertungwinform\Form1.h 38
    Fehler 5 fatal error LNK1120: 2 nicht aufgelöste externe Verweise. C:\Dokumente und Einstellungen\skuemmri\Eigene Dateien\Visual Studio 2008\Projects\ZeusSimAuswertungWinForm\Debug\ZeusSimAuswertungWinForm.exe
    Fehler 2 error LNK2031: p/invoke konnte nicht für ""extern "C" void __clrcall float3DFeldLaden(char *,float * * *,int,int,int,int,int,int)" (?float3DFeldLaden@@$$J0YMXPADPAPAPAMHHHHHH@Z)" generiert werden. In den Metadaten fehlt die Aufrufkonvention. ZeusSimAuswertungWinForm.obj
    Fehler 3 error LNK2028: Nicht aufgelöstes Token (0A000015) ""extern "C" void __clrcall float3DFeldLaden(char *,float * * *,int,int,int,int,int,int)" (?float3DFeldLaden@@$$J0YMXPADPAPAPAMHHHHHH@Z)", auf das in Funktion ""private: void __clrcall ZeusSimAuswertungWinForm::Form1::btn_schallfeld_laden_Click(class System::Object ^,class System::EventArgs ^)" (?btn_schallfeld_laden_Click@Form1@ZeusSimAuswertungWinForm@@$$FAAAMXPAAMXPAAVObject@System@@PAAVEventArgs@4@@Z)" verwiesen wird. ZeusSimAuswertungWinForm.obj Fehler 4 error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""extern "C" void \_\_clrcall float3DFeldLaden(char *,float * * *,int,int,int,int,int,int)" (?float3DFeldLaden@@J0YMXPADPAPAPAMHHHHHH@Z)"inFunktion""private:void__clrcallZeusSimAuswertungWinForm::Form1::btn_schallfeld_laden_Click(classSystem::Object,classSystem::EventArgs)"(?btn_schallfeld_laden_Click@Form1@ZeusSimAuswertungWinForm@@J0YMXPADPAPAPAMHHHHHH@Z)" in Funktion ""private: void \_\_clrcall ZeusSimAuswertungWinForm::Form1::btn\_schallfeld\_laden\_Click(class System::Object ^,class System::EventArgs ^)" (?btn\_schallfeld\_laden\_Click@Form1@ZeusSimAuswertungWinForm@@FAFAAAMXPAAVObject@System@@PAAVObject@System@@PAAVEventArgs@4@@Z)". ZeusSimAuswertungWinForm.obj

    Viel kann ich diesen Fehlern/Warnungen nicht entnehmen 😕



  • Du darfst die "dllimport" nicht innnerhalb einer Klasse vornehmen. Du musst noch "__cdecl oder __stdcalll angeben.



  • Die dllimport steht bei mir in der Form1.h. Sollte die etwa woanders hin? Und wo geb ich das __cdecl bzw. das __stdcall an?



  • mit

    extern "C" __declspec(dllimport) void __cdecl float3DFeldLaden(char* Dateiname, float ***feld, ...);
    

    lässt sich das Projekt zumindest kompilieren. Komm ich dann aber zu dem Aufruf der Funktion float3DFeldLaden, dann heißt es:

    Eine nicht behandelte Ausnahme des Typs "System.DllNotFoundException" ist in ZeusSimAuswertungWinForm.exe aufgetreten.

    Zusätzliche Informationen: Die DLL "UTzeusPAFeld.dll": Das angegebene Modul wurde nicht gefunden. (Ausnahme von HRESULT: 0x8007007E) kann nicht geladen werden.

    und das kommt mir irgendwoher bekannt vor.



  • Dann solltest Du auch noch die DLL in den PFAD legen oder zumindest in das gleiche Verzeichnis wie die EXE.



  • Das hab ich natürlich getan.



  • Ok, Problem gefunden. Ich hatte die dll zwar beim Projektmappenexplorer hinzugefügt, aber sie war nicht mit eingebunden. Rechtsklick drauf unter Eigenschaften offenbarte sich die Option "Zu Projekt hinzufügen", welche auf false stand. Das hab ich diese mal ganz dezent auf true gestellt und wundersammerweise funktioniert es nun. Auf jeden Fall danke für deine Hilfe.



  • Ich wollte einfach nur mal Danke sagen, genau solche Beiträge helfen einem weiter! Denn ich hatte genau das gleiche Problem und die klaren Antworten haben mich innerhalb kürzester Zeit an mein Ziel gebracht.

    👍


Anmelden zum Antworten