PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : DLL erstellen für Dummies


Dr.Doom
2014-09-17, 16:08:35
Howdy,

ich versuche eine einfache DLL zu erstellen, um "Schulungsmaterial" für Python in Verbindung mit ctypes zu haben.

In der DLL sollen so komplexe Funktionen drin sein, wie bspw.


ctypes_tester.cpp

...
CTYPES_TESTER_API int function_one(void)
{
return 42;
}

CTYPES_TESTER_API float function_two(float f)
{
return f;
}
...


ctypes_test.h
...
#ifdef CTYPES_TESTER_EXPORTS
#define CTYPES_TESTER_API __declspec(dllexport)
#else
#define CTYPES_TESTER_API __declspec(dllimport)
#endif

CTYPES_TESTER_API int function_one(void);
CTYPES_TESTER_API float function_two(float f);
...


Ich kann auf die DLL in Python zwar zugreifen
print ctypes.cdll.LoadLibrary("ctypes_tester.dll")
>>> <CDLL 'ctypes_tester.dll', handle f780000 at 1d977f0>

Aber beim Zugriff auf eine der Funktionen gibt es dann einen Fehler:
AttributeError: function 'function_one' not found


"Fertige" DLLs habe ich schon 10000x in Python genutzt, aber ich hab' noch nie eine selber erstellt, daher weiss ich nicht, was ich falsch gemacht haben könnte oder wo man nun zu drehen hat.

Ich habe in VS2013 einfach ein neues Win32-Projekt gestartet, im Folgedialog "DLL" angehakt und dann "Fertig" gedrückt.
Nun habe ich drei Headerdateien "ctypes_tester", "stdafx" und "targetver", sowie drei Quelldateien "ctypes_tester", "dllmain" und "stdafx".

Was ich in die ctypes_tester-Dateien geschrieben habe, sieht man oben, den Rest habe ich nicht angefasst.

Hat jemand einen Tipp für'n C-Analphabeten?

EDIT: Aufrufkonvention ist in den Projekteigenschaften auf __cdecl gestellt.

del_4901
2014-09-17, 16:16:08
http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx

Marscel
2014-09-17, 16:18:00
Wie wäre es mit

thedll = ctypes.cdll.LoadLibrary("ctypes_tester.dll")
thedll.function_one()

Dr.Doom
2014-09-17, 18:08:35
http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspxIst ja bereits so gemacht, siehe oben.

Wie wäre es mit

thedll = ctypes.cdll.LoadLibrary("ctypes_tester.dll")
thedll.function_one()Genauso steht's im Python-Skript (ok, die Variable heisst anders). Habe ich natürlich vergessen hinzuschreiben, sorry. Nach der Ausführung erhalte ich dann den oben genannten Fehler.

del_4901
2014-09-17, 18:16:07
http://www.nirsoft.net/utils/dll_export_viewer.html

Marscel
2014-09-17, 18:34:34
Und CTYPES_TESTER_EXPORTS ist auch sicher definiert? Womit wird cl.exe ausgeführt? Klappt hier nämlich.

Achja, du kompilierst ja eine cpp-Datei. Dann benutz eine Signatur wie:

#define CTYPES_TESTER_API extern "C" __declspec(dllexport)

Sonst werden die Symbole namegemangeld, bekommen also einen abweichenden Namen.

Dr.Doom
2014-09-17, 19:02:00
Und CTYPES_TESTER_EXPORTS ist auch sicher definiert? Womit wird cl.exe ausgeführt? Klappt hier nämlich.

Achja, du kompilierst ja eine cpp-Datei. Dann benutz eine Signatur wie:

#define CTYPES_TESTER_API extern "C" __declspec(dllexport)

Sonst werden die Symbole namegemangeld, bekommen also einen abweichenden Namen.

Kann ich erst morgen prüfen, aber wenn VS2013 mir zu ein Grundgerüst vorsetzt, will ich mal hoffen, dass die wissen, was sie tun :ugly: , sodass ich davon ausgehe, DASS es definiert ist.

nach dem Edit EDIT: Hmm, ok... ich erinnere mich dunkel. Da war doch was mit C++ und Überladen von Funktionen. Der tatsächlich exportierte Name ist dann um irgendeinen Schnörkel, wo vmtl die Signatur mit verschnauselt ist, ergänzt, sodass der Zugriff von Python aus gar nicht klappen kann, weil man das Anhängsel am Funktionsnamen noch bräuchte.
Hach, Fachbegriffe nutzen ist schon was feines.


Ein Tag später EDIT: Ja, es lag tatsächlich am 'export "C"'. Vielen Dank für die Guldung dummer Fragen. :)