DLL in Python nutzen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Avon
User
Beiträge: 6
Registriert: Dienstag 20. November 2007, 08:23

Hallo,

ich weiss dieses Thema wurde bestimmt bereits mehrfach hier im Thema behandelt und ich habe auch genug darüber gelesen, doch ich finden einfach meinen Fehler nicht.

Ich habe mittels VC++6.0 eine sehr einfache DLL erstellt. Hier mein cpp File:

Code: Alles auswählen

#include "stdafx.h"
#include "abc_dll.h"


BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}

DllExport int fnAbc2_dll(int abcd)
{
	return ++abcd;
}
und hier die zugehörige Header Datei:

Code: Alles auswählen

#define DllImport   __declspec( dllimport )
#define DllExport   __declspec( dllexport )

extern "C" DllExport int fnAbc2_dll(int abcd);
Jetzt wollte ich das ganze in Python nutzen. Der Code dazu sieht folgendermaßen aus:

Code: Alles auswählen

import ctypes

dll = ctypes.windll.LoadLibrary("abc_dll.dll")
ret = dll.fnAbc2_dll(10)
print ret
Wenn ich das ganze ausführe erhalte ich folgende Fehlermeldung:
Traceback (most recent call last):
File "C:\tmp\abc_py\test.py", line 26, in <module>
ret = dll.fnAbc2_dll(10)
ValueError: Procedure probably called with too many arguments (4 bytes in excess)

Woran könnte das liegen? In der Dokumentation findet man zu diesem Thema nur den tollen Hinweis, mann solle sich den C-Header ansehen. Doch der Aufruf sollte bei mir stimmen. Wo könnte also der Fehler liegen.

Danke im Vorraus.
BlackJack

Hilft es wenn Du in Python auch *sagst*, dass die Funktion ein `int` entgegennimmt?
Avon
User
Beiträge: 6
Registriert: Dienstag 20. November 2007, 08:23

meinst du so etwas?:

Code: Alles auswählen

myInt = ctypes.c_int(10)
ret = dll.fnAbc2_dll(myInt)
Ergibt den gleichen Fehler.
BlackJack

Nein ich meine der Funktion sagen was sie für Argumente entgegennimmt.

Code: Alles auswählen

fnAbc2_dll = dll.fnAbc2_dll
fnAbc2_dll.argtypes = [ctypes.c_int]
Avon
User
Beiträge: 6
Registriert: Dienstag 20. November 2007, 08:23

Nein, das hat keinen Effekt. Vieleicht sonst noch ein paar Ideen?
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Etwas am eigentlichen Problem vorbei, aber was passiert wen du den C++ Code so anpasst das er einen long entgegen nimmt?
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Avon
User
Beiträge: 6
Registriert: Dienstag 20. November 2007, 08:23

Das hat ebenfalls keine Auswirkung, warum auch. Das Problem liegt irgendwo anders. Übrigens habe ich vergessen zu sagen, dass ich die DLL aus einer C-Applikation problemlos aufrufen kann.
Gromit
User
Beiträge: 51
Registriert: Montag 8. Mai 2006, 19:07

Ich hab zwar grad keinen C(++)-Compiler unter Windows zur Hand, würde aber pfeilgrad sagen, daß Du deine Funktion mit C-Calling-Convention definiert hast, die DLL aber mit Pascal-Calling-Conventions aufrufst.

Ersetze einfach:

Code: Alles auswählen

dll = ctypes.windll.LoadLibrary("abc_dll.dll")
durch:

Code: Alles auswählen

dll = ctypes.cdll.LoadLibrary("abc_dll.dll")
HTH,
Gerald
Master of Calling Convention Desaster
Avon
User
Beiträge: 6
Registriert: Dienstag 20. November 2007, 08:23

Oh man genau das war es! Kleiner Fehler große Wirkung.

Danke!
Antworten