Seite 1 von 1

DLL in Python nutzen

Verfasst: Dienstag 20. November 2007, 08:40
von Avon
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.

Verfasst: Dienstag 20. November 2007, 08:56
von BlackJack
Hilft es wenn Du in Python auch *sagst*, dass die Funktion ein `int` entgegennimmt?

Verfasst: Dienstag 20. November 2007, 09:12
von Avon
meinst du so etwas?:

Code: Alles auswählen

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

Verfasst: Dienstag 20. November 2007, 09:28
von 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]

Verfasst: Dienstag 20. November 2007, 11:07
von Avon
Nein, das hat keinen Effekt. Vieleicht sonst noch ein paar Ideen?

Verfasst: Dienstag 20. November 2007, 11:14
von veers
Etwas am eigentlichen Problem vorbei, aber was passiert wen du den C++ Code so anpasst das er einen long entgegen nimmt?

Verfasst: Dienstag 20. November 2007, 11:47
von Avon
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.

Verfasst: Dienstag 20. November 2007, 13:30
von Gromit
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

Verfasst: Dienstag 20. November 2007, 15:49
von Avon
Oh man genau das war es! Kleiner Fehler große Wirkung.

Danke!