Python & amp; Ctypes: Passer une structure à une fonction en tant que pointeur pour récupérer des données

J'ai regardé à travers d'autres réponses, mais ils ne peuvent pas sembler obtenir que cela fonctionne. J'essaie d'appeler une fonction dans une DLL pour communiquer avec SMBus appareils. Cette fonction reçoit un pointeur vers une struct, qui a un tableau comme l'un de ses champs. alors...

Dans C:

typedef struct _SMB_REQUEST
{
    unsigned char Address;
    unsigned char Command;
    unsigned char BlockLength;
    unsigned char Data[SMB_MAX_DATA_SIZE];
} SMB_REQUEST;

Je pense que j'ai pour définir les valeurs de l'Adresse, de Commande et de BlockLength alors que la DLL remplit le tableau de Données.
La fonction qui a besoin de cette structure prend comme un pointeur

SMBUS_API int SmBusReadByte( SMBUS_HANDLE handle, SMB_REQUEST *request );

Donc j'ai mis en place la structure en Python comme suit:

class SMB_REQUEST(ctypes.Structure):
    _fields_ = [("Address", c_char),
            ("Command", c_char),
            ("BlockLength", c_char),
            ("Data", type(create_string_buffer(SMB_MAX_DATA_SIZE))]

*Note: j'ai aussi essayé de ctypes.c_char*SMB_MAX_DATA_SIZE pour le type de données*

Pour passer un pointeur vers une structure de ce type à la fonction, j'ai essayé de réagir, d'abord comme suit:

data = create_string_buffer(SMB_MAX_DATA_SIZE)
smb_request = SMB_REQUEST('\x53', \x00', 1, data)

Cela répond:

TypeError: expected string or Unicode object, c_char_Array_32 found

Si j'essaie de quitter le tableau de données, comme suit:

smb_request = SMB_REQUEST('\x53', \x00', 1)

Non, erreur.
Cependant, lorsque j'essaie de la transmettre à la fonction:

int_response =  smbus_read_byte(smbus_handle, smb_request))

J'obtiens:

ArgumentError: argument 2: <type 'exceptions.TypeError'>: expected LP_SMB_REQUES
T instance instead of SMB_REQUEST

J'ai essayé de le transmettre comme un pointeur:

int_response =  smbus_read_byte(smbus_handle, ctypes.POINTER(smb_request))

et j'obtiens:

----> 1
      2
      3
      4
      5

TypeError: must be a ctypes type

Voici comment j'ai configuré l'art types:

smbus_read_byte.argtypes = (ctypes.c_void_p, ctypes.POINTER(SMB_REQUEST))

J'ai essayé de casting mais toujours pas aller. Quelqu'un peut-il éclairer sur ce pour moi?

Mise à jour:

Si j'ai d'abord initialiser la structure comme suit:

smb_request = SMB_REQUEST('\xA6', '\x00', chr(1), 'a test string')

et puis la basse par la référence:

int_response =  smbus_receive_byte(smbus_handle, ctypes.byref(smb_request))

Je n'obtiens pas d'erreur. Cependant, la fonction retourne -1 si elle doit retourner '0' pour la réussite et non nulle pour un échec. De vérifier la valeur de smb_request.Données de retour d'une chaîne de test' donc pas de changement.
Toutes les suggestions sur ce qui pourrait se passer ici serait grandement apprécié.

Grâce

Mise à JOUR:

Depuis que j'ai reçu quelques demandes de renseignements au sujet de savoir si ma poignée est correct, voici comment je l'utilise. L'en-tête de fichier de la DLL déclare ce qui suit:

typedef void *SMBUS_HANDLE;

//
// This function call initializes the SMBus, opens the driver and 
// allocates the resources associated with the SMBus.
// All SMBus API calls are valid 
// after making this call except to re-open the SMBus.
//
SMBUS_API SMBUS_HANDLE OpenSmbus(void);

Donc voici comment j'ai fais ça en python:

smbus_handle = c_void_p() # NOTE: I have also tried it without this line but same result

open_smbus = CDLL('smbus.dll').OpenSmbus
smbus_handle =  open_smbus()
print 'SMBUS_API SMBUS_HANDLE OpenSmbus(void): ' + str(smbus_handle)

J'appelle cela avant de faire l'appel à smbus_read_byte(). J'ai essayé de mettre open_smbus.restype = c_void_p() mais j'obtiens une erreur: TypeError: restype must be a type, a callable, or None

source d'informationauteur Jack | 2010-12-04