Anbindung DLL an Python
@thomasgull: Naja korrekter eher einen Speicherbereich in den man bis zu 21 Bytes ablegen kann. Ob da vor dem Aufruf Daten drinstehen die als C-String durchgehen und bei `strlen()` tatsächlich 20(!) als Ergebnis liefern ist egal. 21 Zeichen kann die Zeichenkette nicht haben, denn dann müsste der Speicherbereich 22 Bytes gross sein.
-
- User
- Beiträge: 48
- Registriert: Samstag 2. Februar 2013, 18:52
Danke mit c_Buffer funktioniert es bestens
Danke
Danke
-
- User
- Beiträge: 48
- Registriert: Samstag 2. Februar 2013, 18:52
Nochmals besten Dank
Langsam habe ich die C-Funktionen begriffen
Langsam habe ich die C-Funktionen begriffen
-
- User
- Beiträge: 48
- Registriert: Samstag 2. Februar 2013, 18:52
Nochmals eine Frage
wie würdet ihr das mit Strukturen lösen?
Bei dieser Funktion werden ganze Strukturen übergeben und danach wieder Ausgelesen.
Beschreibung:
Erweiterter Leseauftrag für Antriebe (AGL_Drive_ReadMixEx)
Mit dieser Funktion können Sie die Werte verschiedener Datentypen und Datengrößen in einem Auftrag lesen. Gegenüber der Funktion AGL_Drive_ReadMix darf hier die Strukturvariable DATA_RW40_DRIVE.OpAnz auch größer 1 sein. Dies bedeutet, dass mit einem Strukturelement mehrere aufeinanderfolgende Operandenwerte gelesen werden können.
C/C++-Syntax:
int WINAPI AGL_Drive_ReadMixEx( int ConnNr, LPDATA_RW40_DRIVE Buff, int Num, int Timeout, LONG_PTR UserVal );
Parameter:
ConnNr Verbindungshandle
Buff Zeiger auf Lesestrukturen
Num Anzahl der Strukturen
Timeout Der zu verwendende Timeoutwert
UserVal Wert zur freien Verwendung
Rückgabewert:
>= 0 Auftragsnummer bei asynchronem Aufruf und synchronem Aufruf mit AGL_ReturnJobNr( 1 ) oder AGL40_SUCCESS bei synchronem Aufruf ohne AGL_ReturnJobNr( 1 )
< 0 Eine Fehlernummer (s. AGL_Defines.H, AGL_Defines.BAS oder AGL_Defines.PAS)
Code in C++
Viele Grüsse
Thomas
wie würdet ihr das mit Strukturen lösen?
Bei dieser Funktion werden ganze Strukturen übergeben und danach wieder Ausgelesen.
Beschreibung:
Erweiterter Leseauftrag für Antriebe (AGL_Drive_ReadMixEx)
Mit dieser Funktion können Sie die Werte verschiedener Datentypen und Datengrößen in einem Auftrag lesen. Gegenüber der Funktion AGL_Drive_ReadMix darf hier die Strukturvariable DATA_RW40_DRIVE.OpAnz auch größer 1 sein. Dies bedeutet, dass mit einem Strukturelement mehrere aufeinanderfolgende Operandenwerte gelesen werden können.
C/C++-Syntax:
int WINAPI AGL_Drive_ReadMixEx( int ConnNr, LPDATA_RW40_DRIVE Buff, int Num, int Timeout, LONG_PTR UserVal );
Parameter:
ConnNr Verbindungshandle
Buff Zeiger auf Lesestrukturen
Num Anzahl der Strukturen
Timeout Der zu verwendende Timeoutwert
UserVal Wert zur freien Verwendung
Rückgabewert:
>= 0 Auftragsnummer bei asynchronem Aufruf und synchronem Aufruf mit AGL_ReturnJobNr( 1 ) oder AGL40_SUCCESS bei synchronem Aufruf ohne AGL_ReturnJobNr( 1 )
< 0 Eine Fehlernummer (s. AGL_Defines.H, AGL_Defines.BAS oder AGL_Defines.PAS)
Code in C++
Code: Alles auswählen
int doDrive_ReadMixEx(int connnr, int timeout, int userval)
{
int num = 3;
LPDATA_RW40 rwfield = (LPDATA_RW40)calloc(num, sizeof(DATA_RW40));
rwfield[0].Dev = 1;
rwfield[0].ParaInd = 0;
rwfield[0].ParaNum = 0;
rwfield[0].OpAnz = 1;
rwfield[0].OpType = DTYP_UNKNOWN;
rwfield[0].Result = 0;
rwfield[0].Buff = (float*)calloc(rwfield[0].OpAnz, sizeof(float));
((float*)rwfield[0].Buff)[0] = 0;
rwfield[1].Dev = 0;
rwfield[1].ParaInd = 1;
rwfield[1].ParaNum = 0;
rwfield[1].OpAnz = 5;
rwfield[1].OpType = DTYP_UNKNOWN;
rwfield[1].Result = 0;
rwfield[1].Buff = (DWORD*)calloc(rwfield[1].OpAnz, sizeof(DWORD));
((DWORD*)rwfield[1].Buff)[0] = 1;
((DWORD*)rwfield[1].Buff)[1] = 0;
((DWORD*)rwfield[1].Buff)[2] = 0;
((DWORD*)rwfield[1].Buff)[3] = 0;
((DWORD*)rwfield[1].Buff)[4] = 0;
rwfield[2].Dev = 0;
rwfield[2].ParaInd = 1;
rwfield[2].ParaNum = 0;
rwfield[2].OpAnz = 1;
rwfield[2].OpType = DTYP_UNKNOWN;
rwfield[2].Result = 0;
rwfield[2].Buff = (byte*)calloc(rwfield[2].OpAnz, sizeof(byte));
((byte*)rwfield[2].Buff)[0] = 1;
// For a successful call, a connection must be built up to the AG.
int result = AGL_DriveReadMixEx(connnr, rwfield, num, timeout, userval);
if (result != AGL40_SUCCESS)
{
// Error happened.
char errormsg[256];
AGL_GetErrorMsg(result, errormsg, 256);
}
// clean up the memory
free(rwfield[0].Buff);
free(rwfield[1].Buff);
free(rwfield[2].Buff);
return result;
}
Viele Grüsse
Thomas
@thomasgull: Was ist denn dabei die konkrete Frage? Wie man Proxy-Objekte für Strukturtypen mit `ctypes` definiert steht in der Python-Dokumentation im `ctypes`-Tutorial.
Und wie man so eine komplette Funktion konkret übersetzt hängt auch ein bisschen davon ab wie man die Python API zu den Funktionen gestaltet. Das wird man ja hoffentlich nicht 1:1 machen sondern eine „pythonische” API entwerfen. Sonst stellt sich nämlich die Frage warum man das überhaupt in Python macht wenn der Code am Ende aussieht wie C-Code in Python-Syntax verkleidet.
In dem gezeigten Quelltext wird der Speicher von `rwfield` nicht wieder freigegeben. Das sieht nach einem Speicherleck aus.
Und wie man so eine komplette Funktion konkret übersetzt hängt auch ein bisschen davon ab wie man die Python API zu den Funktionen gestaltet. Das wird man ja hoffentlich nicht 1:1 machen sondern eine „pythonische” API entwerfen. Sonst stellt sich nämlich die Frage warum man das überhaupt in Python macht wenn der Code am Ende aussieht wie C-Code in Python-Syntax verkleidet.
In dem gezeigten Quelltext wird der Speicher von `rwfield` nicht wieder freigegeben. Das sieht nach einem Speicherleck aus.