Anbindung DLL an Python

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
BlackJack

@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.
thomasgull
User
Beiträge: 48
Registriert: Samstag 2. Februar 2013, 18:52

Danke mit c_Buffer funktioniert es bestens

Danke
thomasgull
User
Beiträge: 48
Registriert: Samstag 2. Februar 2013, 18:52

Nochmals besten Dank
Langsam habe ich die C-Funktionen begriffen
thomasgull
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++

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
BlackJack

@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.
Antworten