Вызов функции argc / argv с помощью ctypes - PullRequest
0 голосов
/ 17 июня 2020

Я создаю оболочку для кода в c для Python. Код c в основном выполняется в терминале и имеет следующий прототип основной функции:

void main(int argc, char *argv[]){
f=fopen(argv[1],"r");
f2=fopen(argv[2],"r");

Итак, в основном считываемые аргументы - это строки в терминале. Я создал следующую оболочку python ctype, но, похоже, я использую неправильный тип. Я знаю, что аргументы, передаваемые с терминала, читаются как символы, но эквивалентная python боковая оболочка выдает следующую ошибку:

import ctypes
_test=ctypes.CDLL('test.so')

def ctypes_test(a,b):
  _test.main(ctypes.c_char(a),ctypes.c_char(b))

ctypes_test("323","as21")



TypeError: one character string expected

Я попытался добавить один символ, просто чтобы проверить, выполняется ли общий объект, он работает так же, как работают команды печати, но на мгновение до тех пор, пока секции кода в общем объекте не потребуется имя файла. Я также пробовал ctypes.c_char_p, но получил.

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

Обновлено в соответствии с предложением в комментариях до следующего:

def ctypes_test(a,b):
      _test.main(ctypes.c_int(a),ctypes.c_char_p(b))
ctypes_test(2, "323 as21")

Тем не менее, возникает та же ошибка.

1 Ответ

1 голос
/ 17 июня 2020

Использование этой тестовой DLL для Windows:

#include <stdio.h>

__declspec(dllexport) void main(int argc, char* argv[])
{
    for(int i = 0; i < argc; ++i)
        printf("%s\n",argv[i]);
}

Этот код вызовет его. argv в основном это char** в C, поэтому тип ctypes - POINTER(c_char_p). Вы также должны передавать байтовые строки, и это не может быть список Python. Это должен быть массив указателей ctypes.

>>> from ctypes import *
>>> dll = CDLL('./test')
>>> dll.main.restype = None
>>> dll.main.argtypes = c_int,POINTER(c_char_p)
>>> args = (c_char_p * 3)(b'abc',b'def',b'ghi')
>>> dll.main(len(args),args)
abc
def
ghi
...