Проблема с CTypes - вызов функции C dll - PullRequest
0 голосов
/ 20 марта 2019

У меня есть следующая функция C, экспортированная из dll

typedef struct _TStubMethod
{
    TBoolean stubAtEnd;
    TBoolean longStub;
} TStubMethod;


int JpmcdsStringToStubMethod
(char        *name,     
 TStubMethod *stubMethod 
);

В Python я определил тип & функцию и вызвал функцию следующим образом:

class TStubMethod(Structure):
    _fields_ = [
        ('stubAtEnd', c_int),
        ('longStub', c_int)
    ]

def JpmcdsStringToStubMethod(dll, name, stubmethod):
    func = dll.JpmcdsStringToStubMethod
    func.argtypes = [POINTER(c_char), POINTER(TStubMethod)]
    func.restype = c_int
    return func(name, stubmethod)

stubFS = TStubMethod(False, False)
ret = JpmcdsStringToStubMethod(dll, 'F/S', byref(stubFS))

Яполучаю ошибку следующим образом.Что я делаю неправильно?

ArgumentError                             Traceback (most recent call last)
<ipython-input-61-ec7303283f89> in <module>
     25 
     26 stubFS = TStubMethod(False, False)
---> 27 ret = JpmcdsStringToStubMethod(dll, 'F/S', byref(stubFS))

<ipython-input-55-c8ab0da16b04> in JpmcdsStringToStubMethod(dll, name, stubmethod)
      9     func.argtypes = [POINTER(c_char), POINTER(TStubMethod)]
     10     func.restype = c_int
---> 11     return func(name, stubmethod)

ArgumentError: argument 1: <class 'TypeError'>: wrong type

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 20 марта 2019

При передаче строк с нулевым символом в конце используйте c_char_p . Согласно [Python 3]: класс ctypes. c_char_p :

Представляет тип данных C char *, когда он указывает на строку с нулевым символом в конце.

Переведено на ваш код:

  1. Изменить функцию argtypes (1 st one):

    func.argtypes = [c_char_p, POINTER(TStubMethod)]
    
  2. Используйте байтов (что эквивалентно Python для char*). Вы можете либо ( не оба):

    • Преобразование строки в байтов (чтобы сохранить изменения в JpmcdsStringToStubMethod ):

      return func(name.encode(), stubmethod)
      
    • Передать байт экземпляр JpmcdsStringToStubMethod :

      ret = JpmcdsStringToStubMethod(dll, b"F/S", byref(stubFS))
      
...