Fehler beim exportieren von Konstruktor aus DLL



  • Hallo! Ich bin neu hier und stelle mal meine erste Frage 🙂 :

    Ich versuche eine Klasse per LoadLibrary und GetProcAddress aus einer DLL zu importieren.
    (Kompiliere auf Windows 7 mit Visual Studio 2010 Express)

    Code der DLL (header datei):

    #include <Windows.h>
    #include <iostream>
    #include <conio.h>
    using namespace std;
    //
    #ifdef DLL_EXPORT
    #define FOV_API __declspec(dllexport)
    #else
    #define FOV_API __declspec(dllimport)
    #endif
    
    class FOV_API user
    {
    public:
    					 user();
    					~user();
    	//void			 SetFov(float fov);
    	//LRESULT CALLBACK MouseHook(int nCode, WPARAM wParam, LPARAM lParam);
    	//BOOL WINAPI		 HandlerRoutine(DWORD dwCtrlType);
    
    private:
    	//float the_fov;
    	//DWORD protection;
    	//HANDLE hMW;
    	//HHOOK hookHandle;
    };
    

    (Habe die Funktionen und variablen erstmal auskommentiert weil ich erstmal den Konstruktor zum laufen bekommen möchte)

    Code der DLL (cpp datei)

    #include "head.h"
    
    user::user()/*:
    the_fov (0),
    protection (0),
    hMW (0),
    hookHandle (0)*/
    {
    	cout << "Ctor called";
    }
    
    //Hier waren noch die Funktionen, aber auch erstmal auskommentiert
    

    (Habe im Preprocessor noch DLL_EXPORT hinzugefügt)

    Hier ist der code der exe von der ich die DLL laden und den Konstruktor ausführen möchte:

    Code der exe (main.cpp)

    #include "head.h"
    using namespace std;
    
    typedef void   (WINAPI * PCTOR) ();
    
    int main()
    {
    	//Load DLL
    	HMODULE hMod = LoadLibrary (L"fov.dll");
    	if(hMod == NULL)
    	{
    		cout << "Error @ LoadLibrary: " << GetLastError() << endl;
    		_getch();
    		return 1;
    	}
    
    	//Alloc mem for class
    	user *pUser = (user *) malloc (sizeof (user));
    	if(NULL == pUser)
    	{
    		cout << "Error @ malloc: " << GetLastError() << endl;
    		_getch();
    		return 1;
    	}
    
    	//ctor
    	PCTOR pCtor = (PCTOR) GetProcAddress (hMod , "??4user@@QAEAAV0@ABV0@@Z"); //nicht wundern, das ist der name der funktion (glaube ich) habe ich per dumpbin.exe /exports fov.dll herausgefunden
    
    	if(pCtor == NULL)
    	{
    		cout << "Error @ GetProcAddress: " << GetLastError() << endl;
    	}
    
    	__asm { MOV ECX, pUser }
    
    	//try to call ctor
    	pCtor();
    
    	_getch();
    	return 0;
    }
    

    Nach diesem 'Tutorial' habe ich den Code angefertigt : http://www.codeproject.com/Articles/9405/Using-classes-exported-from-a-DLL-using-LoadLibrar

    Also : Wenn ich das alles jetzt kompiliere bekomme ich folgenden error :

    Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

    Die Calling convention (WINAPI also __stdcall) müsste eigentlich korrekt sein!

    Bitte helft mir, habe sehr lange nach einer Lösung gesucht aber nichts gefunden!

    (PS: Ich möchte NICHT einfach das HeaderFile einfügen und dann das .lib file linken 😃 )



  • AFAIK sind Memberfunktion standardmäßig nicht stdcall, sondern thiscall. Deshalb der Fehler.

    Allerdings muss ich dazusagen dass es generell keine gute Idee ist das so zu lösen, du siehst ja dass es bei C++ nicht ganz so simpel ist eine Memberfunktion aus einer DLL zu impotieren, so einen Hack würde ich für nichts produktives einsetzen, nur zum testen.
    Was spricht denn gegen eine C-Schnittstelle ?



  • DarkShadow44 schrieb:

    AFAIK sind Memberfunktion standardmäßig nicht stdcall, sondern thiscall. Deshalb der Fehler.

    Allerdings muss ich dazusagen dass es generell keine gute Idee ist das so zu lösen, du siehst ja dass es bei C++ nicht ganz so simpel ist eine Memberfunktion aus einer DLL zu impotieren, so einen Hack würde ich für nichts produktives einsetzen, nur zum testen.
    Was spricht denn gegen eine C-Schnittstelle ?

    Danke für die Antwort!
    Mit __thiscall bekomme ich leider genau den selben Fehler!

    Genau so ist es, ich will es testen (und auf jeden fall zum laufen bringen)!



  • Oh mein gott... Es tut mir leid, mir ist ein Fehler unterlaufen : Ich habe versucht den Destructor zu erstellen ... Wenn ich weitere Fehler bekomme schreibe ich nochmal 🙂



  • Muss ich die Funktionspointer nach Benutzung löschen oder passiert das mit FreeLibrary ?

    Wäre es wenn ich das ganze nämlich in eine Funktion verpacke und diese ein 2tes mal aufrufe und die pointer ihre adresse wieder neu zugewiesen bekommen nicht besser die pointer zu löschen und auf NULL zu setzen ?



  • Ceno schrieb:

    Muss ich die Funktionspointer nach Benutzung löschen oder passiert das mit FreeLibrary ?

    FreeLibrary

    Ceno schrieb:

    Wäre es wenn ich das ganze nämlich in eine Funktion verpacke und diese ein 2tes mal aufrufe und die pointer ihre adresse wieder neu zugewiesen bekommen nicht besser die pointer zu löschen und auf NULL zu setzen ?

    Hä???
    Verwende lokale Variablen wenn du die Zeiger immer neu holen willst.
    Oder sonst halt glokale Variablen, die du nur 1x befülst - denn die Adresse einer Funktion ändert sich nicht so lange die DLL geladen ist.



  • Stimmt, Lokale Variablen! Hätte ich auch so drauf kommen können! Danke 🙂


Anmelden zum Antworten