Typproblem C++ --> Delphi XE5

    Typproblem C++ --> Delphi XE5

    Hi,
    ich verzweifle langsam an einer C++-DLL-Funktion, die ich von Delphi XE5 aus aufrufen möchte. Die DLL-Funktion gibt mir immer NULL zurück. Unter Windows 7 hat es noch funktioniert, seit Win 8 und 10 nicht mehr. Ich möchte zunächst mal sichergehen, dass ich die C++-Typen richtig konvertiert habe.

    Funktionsdeklaration in der .H-Datei:

    Quellcode

    1. #ifdef _WIN32
    2. #define HID_API_EXPORT __declspec(dllexport)
    3. #define HID_API_CALL
    4. #else
    5. #define HID_API_EXPORT /**< API export macro */
    6. #define HID_API_CALL /**< API call macro */
    7. #endif
    8. #define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/
    9. (...)
    10. HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path);


    Meine Funktionsdeklaration in XE5 - ich kompiliere eine 64Bit-Datei, daher nehme ich stdcall:
    function OpenHidByPath(const Path: PAnsiChar): PHidDevice; stdcall; external 'hidapi.dll' name 'hid_open_path';

    Schon mal herzlichen Dank für Hinweise und Tipps,
    Christian

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „charraeus“ ()

    Ja, das passt so alles. Die Defines spielen keine Rolle für deinen Delphi-Import, die stellen nur sicher, dass die DLL auch tatsächlich diese Funktion exportiert. Das kannst du auch mit DLLExp nachprüfen, dort sollte die Funktion aufgelistet sein.
    StdCall spielt keine Rolle. Unter Win64 gibt es nur noch eine einzige Aufrufkonvention - StdCall, Cdecl und auch Register sind alle identisch. Dementsprechend erledigt sich auch die erste Vermutung, dass du nicht StdCall sondern Cdecl verwenden solltest. Unter 32-Bit ist das nämlich der Standard; __stdcall müsste extra angegeben werden. Ich weiß nicht, ob es bei dem verwendeten Compiler der C-Bibliothek eine globale Option gibt, dass alle Exporte standardmäßig __stdcall sein sollen - wenn das nicht so ist, wäre Cdecl das Richtige. Aber wie gesagt, unter 64-Bit ist das alles egal.
    Ansonsten wurde alles korrekt übersetzt. Die Frage ist vielleicht noch, was hid_device ist, falls das intern schon als Pointer gehandhabt wird, was ich aber eher für unwahrscheinlich halte - vermutlich ist es ein Record, oder? Außerdem erklärt das nicht, wieso NIL rauskommt, das würde höchstens ungültige Daten erklären.
    Allerdings ist eine Sache merkwürdig: #ifdef _WIN32 - sprich, deine Funktion wird nur unter Win32 exportiert! Du musst die DLL aber für Win64 compiliert haben (sonst kannst du sie ja nicht in einem 64-Bit-Programm verwenden), und da wird keine Exportspezifikation mitangegeben. Überprüfe mal mit DLLExp (64-Bit-Version), ob wirklich die Funktion exportiert wird. Allerdings hätte das auch unter Windows 7 schon nicht gehen sollen.
    Master of the EDH ;)
    Grundsätzlich ja, aber nur, wenn spezielle Shared-Memory-Typen verwendet werden (String/dynamische Arrays oder aber Allokieren von Speicher in der DLL/Anwendung in Freigeben im jeweils anderen Teil). Das wird mit einer C(++)-DLL eh nicht funktionieren, weil die DLL ebenfalls ShareMem verwenden müsste. Aber ich sehe jetzt nicht, dass hier solche Typen übergeben würden.
    Master of the EDH ;)
    Danke für die ausführliche Antwort. Ich habe jetzt den C++-Code selbst nochmal übersetzt und erhalte viele Meldungen in der Art
    warning C4267: 'function' : conversion from 'size_t' to 'ULONG', possible loss of data

    Ich nehme an, da muss ich tiefer einsteigen, da die C++-Lib wohl eher für 32Bit gedacht ist ...

    Liebe Grüße und nochmals herzlichen Dank,
    Christian
    Jein; ich habe neulich Poppler mit sämtlichen Abhängigkeiten compiliert. Was ich da so an Warnungen bekommen habe, geht auf keine Kuhhaut. Warnungen dieses Typs spielen nicht unbedingt eine Rolle, sofern du die DLL in der Konfiguration compilierst, für die sie gedacht ist. Einfach die Plattform auf x64 zu ändern, ohne dass das Projekt dafür ausgelegt wurde, ist allerdings sehr wahrscheinlich problematisch. Was mich nur wundert ist deine Aussage, dass es unter Win7 funktioniert hat. Denn das Betriebssystem sollte eigentlich keine Rolle spielen - außer, du hast auf Win7 die Applikation als 32-Bit compiliert. Dann ist klar, wo das Problem liegt.
    Master of the EDH ;)