DLL Probleme

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • DLL Probleme

    Hi, ich habe derzeit ein Problem zwischen dem GM und DLLs, weshalb ich die HauptDLL erstmal in den Hintergrund gestellt habe und zum Test eine MessageBox DLL programmiert habe, doch dort treten die selben Probleme auf.
    Hier erstmal die DLL und die gmk Datei: dlltest.rar
    Das erste Problem ist, dass meine DLL nur strings empfängt aber keine Reals. Ich wollte nämlich innerhalb der DLL eine switch Abfrage einbauen, die den Messageboxtyp, den man der DLL als 3. Parameter übergibt, verarbeitet und somit eine MessageBox erstellt. Das Problem ist, dass die DLL den int Wert nicht empfängt. Die beiden Strings (für den Text und den Titel) werden empfangen aber nicht der Integer.
    Das zweite Problem ist, wenn man das Programm startet, dass der GM gleich einen unexpectet error ausgibt, wenn ich versuche, direkt unter den external_define Funktionen einen external_call einzubauen:

    GML-Quellcode

    1. dll = "dlltest.dll";
    2. global.CGMInit = external_define(dll,"InitializeCGM", dll_stdcall, ty_real, 0);
    3. global.CGMShowMessage = external_define(dll,"ShowMessage", dll_stdcall, ty_real, 2, ty_string, ty_string);
    4. external_call(global.CGMInit); //Das erzeugt einen Fehler...


    Übrigens habe ich hier die Reals gleich ausm Spiel genommen. Wenn ich jedenfalls den Code so umbaue:

    GML-Quellcode

    1. global.CGMShowMessage = external_define(dll,"ShowMessage", dll_stdcall, ty_real, 3, ty_string, ty_string, ty_real);

    Dann empfängt die DLL diesen Integer eben nicht (bzw. er ist immer 0).

    Das zweite Problem ist, dass wenn ich z.B. eine MessageBox mit dem VK_ENTER Event anzeigen lassen will, dann wiederholt er diesen Befehl dauerhaft, wenn ich auf OK klicke (d.h. Taskmanager -> Prozess beenden). Wenn ich jedoch vor den Funktionsausruf die GM Funktion "show_message();" einbaue, passiert es komischerweise nicht:

    VK_Enter Event:

    GML-Quellcode

    1. CGM_ShowMessage("MessageBoxText", "MessageBoxCaption"); // Dauerhaftes anzeigen

    VK Enter Event:

    GML-Quellcode

    1. show_message("...");
    2. CGM_ShowMessage("MessageBoxText", "MessageBoxCaption"); //Hier passiert nichts


    Daraus folgt auch ein weiteres Problem und zwar ist es, dass ihc nicht mehrere Messages hintereinander anzeigen lassen kann. Also den Befehl CGM_ShowMessage mehrmals hintereinander (er zeigt nur die erste Messagebox an).

    Wo ist in dem Example das Problem? Ich steh im Moment echt aufm Schlauch, weil ich das Problem einfach nicht finde. Ich hoffe, da ist jemand von euch besser im finden als ich.

    An der DLL sollte es eigentlich auch nicht liegen. Es sind alles __stdcalls und mit __cdecl Funktionsaufrufen (natürlich dann auch im GM umgestellt) funktioniert es ebenfalls nicht.

    mfg Critical
  • Ich hoffe, dass ich das richtig verstanden hab. Vielleicht wäre es eine Lösung, wenn du den 3. Parameter als String übernimmst und in dem Script umwandelst, bevor du mit der DLL interagierst:
    real(str) Turns str into a real number. str can contain a minus sign, a decimal dot and even an exponential part.
    Ich weiß, das ist nicht ganz das, was du erwartest, aber vielleicht kannst du das Problem damit umgehen.
    █████ ██ █ ████ everything ███ █████ is █████ ████ ████ fine ████ ███ █ ██████ love.
    █████ ███████ ███ your █████ ████ government.
  • Das verstehe ich jetzt nicht ganz. Wo soll ich da einen String umwandeln? Wenn ich jetzt. z.B. die Funktion:

    CGM_ShowMessage("Text", "Caption", 2); aufrufe, dann brauch ich den 3. Parameter eh nicht mehr umwandeln. Ich hatte vorher sowieso immer eine is_real(); und is_string(); abfrage, sodass man eigentlich keien Falschangaben machen kann. Mir fällt in diesem Moment ein, dass ich natürlich das auch in der DLL machen könnte. D.h. die DLL empfängt den 3. Parameter als String und arbeitet dann eben mit chars und nicht mit integern. Das Problem ist nur, dass das Problem mit den Reals trotzdem nicht gelöst ist. Die MessageBox Funktion sah vorher so aus:

    CGM_ShowMessage(hwnd, text, caption, messageboxtype, buttontype); (Die beiden letzten Parameter sind auseinander gehalten, da man das im GM nicht wirklich zusammen realisieren kann.

    Jedoch ist das Problem, dass ich das window handle sowieso als real übergeben muss ( Funktion: window_handle(); ) und dafür brauch ich reals. Das mit dem hwnd habe ich rausgenommen und in der DLL dann so realisiert, dass sie das handle der Messagebox das aktive Fenster (GM Fenster) ist.

    Trotzdem Danke!

    Edit: Wenn du die GMK ausführst, kommt bei dir ein unexpected error?

    mfg Critical
  • Ich meinte es so, dass das in dem Script umgewandelt wird, bevor es mit der DLL interagiert. So würde jedenfalls der GM-User nichts davon mitbekommen. Der Fehler tritt bei mir auch auf, ja. Ich kann leider nicht nachvollziehen, warum. Sowohl der Code im Create Event, als auch das Script, sind in Ordnung.
    █████ ██ █ ████ everything ███ █████ is █████ ████ ████ fine ████ ███ █ ██████ love.
    █████ ███████ ███ your █████ ████ government.
  • Vielleicht liegt es daran, dass du in der DLL ein integer entgegen nimmst. Der GM real Datentyp entspricht aber zB in C++ dem double Typ, sodass du auch in der DLL nur den double Typ verwenden darfst, statt dem int. Am einfachsten wäre es wohl wirklich, wenn du mal den Source postest. (Das mit dem real/double steht aber auch irgendwo in der GM Hilfe). Außerdem dürfen es bei mehr als 4 Funktionsparametern nur noch real Parameter sein, keine strings mehr.
    “Computers are good at following instructions, but not at reading your mind.” (Donald Knuth)

    Ich schreibe mit Neo.
  • Erstmal danke für die Sache mit dem Integer, das hab ich doch komplett vergessen. Ob die DLL mit double jetzt so Funktioniert, wie ich es will, weiß ich noch nicht. Ich hab sie noch nicht getestet.

    C-Quellcode

    1. #define WIN32_LEAN_AND_MEAN
    2. #include <windows.h>
    3. #ifdef __cplusplus
    4. #define EXPORT extern "C" __declspec (dllexport)
    5. #else
    6. #define EXPORT __declspec (dllexport)
    7. #endif
    8. EXPORT double InitializeCGM();
    9. EXPORT double ShowMessage(char *strText, char *strCaption);
    10. #pragma data_seg ("Shared")
    11. HWND hwnd = 0;
    12. #pragma data_seg ()
    13. #pragma comment (linker, "/section:Shared,RWS")
    14. EXPORT double InitializeCGM()
    15. {
    16. //Dies ist noch die umständliche Version, das hwnd zu übergeben, da es mit window_handle(); ja nicht funktioniert hat...
    17. if(GetActiveWindow() == HWND_DESKTOP)
    18. {
    19. MessageBox(GetActiveWindow(), "Fehler beim Initialisieren der cgm.dll!\nFehler: \"Handled window undeclared!\"", "Fehler!", MB_ICONERROR);
    20. return -1;
    21. }
    22. else
    23. {
    24. hwnd = GetActiveWindow();
    25. return 0;
    26. }
    27. }
    28. EXPORT double ShowMessage(char *strText, char *strCaption)
    29. {
    30. return MessageBox(hwnd, strText, strCaption, MB_OK);
    31. }
    Alles anzeigen


    Das Problem ist: Wenn ich die Aufrufkonvention auf __cdecl stelle geht es, bei __stdcall kommt wiegesagt die "error defining an external function", obwohl ich eine DEF datei benutze.

    Edit: Das Problem ist gelöst! Es lag wirklich nur an der Sache mit real und double! Danke für eure Hilfe. Das Problem mit __stdcall und __cdecl ist jedoch immer noch nicht gelöst, dann werde ich wohl immer __cdecl als Aufrufkonvention benutzen müssen.

    mfg Critical

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Critical ()

  • Hmm ich habe diese Zeile rausgenommen, aber es geht wohl immer noch nicht. Ich wüsste auch nicht, warum es dadurch funktionieren soll, da diese Zeile nur ein paar Headerdateien, die selten verwendet werden, ausschließt. Der GM wirft mir jedenfalls immer noch diese Fehlermeldung aus. Vielleicht sollte zu erwähnen sein, dass ich MS VC++ 08 Pro verwende und nicht Dev-C++, weil ich meine, dass es in Dev-C++ mal funktioniert hat.

    mfg Critical