Вызов функции C из Python (без возвращаемого значения)

Я использовал SWIG для подключения моей программы C++ с помощью Python. Из cFunctions.py я вызываю C функцию с именем checkVal следующим образом:

lib = cdll.LoadLibrary('./test.so')

    xml_bytesTrx = bytearray(b'<xml>...</xml>')
    a1  = (ctypes.c_byte*513)(*xml_bytesTrx)

    class EFT_TRX(Structure):
        _fields_ = [
                    ("a2",c_ulong),
                    ("a3",c_char*16),
                    ("a4",c_char*4),
                    ("a5",c_ushort),
                    ("a6",c_char*41),
                    ("a7",c_char*13),
                    ("a8",c_char*21),
                    ("a1",c_byte*513)
                    ]


    Trx = EFT_TRX(0,"0",'CHF',0,'4506445638161117',"123456123456","202020",
                   a1)
def check(arg1, arg2):

    eftTransactionRes = lib.checkVal(arg1,arg2,Trx.a4,Trx.a5,
                                   Trx.a6,Trx.a7,Trx.a8,
                                   Trx.a1)

    Trx.a3 = arg2
    return eftTransactionRes

И в файле заголовка C (test.h) определяется следующим образом:

long TEST_API checkVal(             
        _IN____ const unsigned long a2, 
        _INOUT_ char a3[16], 
        _IN____ const char a4[4], 
        _IN____ const unsigned short a5, 
        _IN____ const char a6[41], 
        _IN____ const char a7[13], 
        _IN____ const char a8[21],
        _INOUT_ char a1[513]
        );

Теперь я написал тестовый код Python для вызова функций C (доступный из cFunctions.py). Проблема в том, что когда я вызываю "проверку" из своего тестового кода (cFunctions.check(10,20)), я достигаю его, но он никогда ничего не возвращает!

Но если я вызову check изнутри cFunctions.py, как это:

check(10,Trx.a2)

Он возвращает результат. Что я делаю не так? Почему проверка не возвращает ничего, когда я вызываю его из моего test.py?

Ответ 1

Помогает ли это? Маленький Гуглинг привел меня сюда!

Вызов функций C из Python - Кристиан Стиген Ларсен

Воспроизведение вышеуказанной ссылки здесь для справки. Я не тестировал код, указанный здесь. Также весь кредит принадлежит автору указанной ссылки.

Вот небольшой учебник о том, как вызывать функции C из Python.

Сделайте некоторые простые функции в C. Мы будем называть файл

myModule.c

#include <Python.h>

/*
 * Function to be called from Python
 */
static PyObject* py_myFunction(PyObject* self, PyObject* args)
{
  char *s = "Hello from C!";
  return Py_BuildValue("s", s);
}

/*
 * Another function to be called from Python
 */
static PyObject* py_myOtherFunction(PyObject* self, PyObject* args)
{
  double x, y;
  PyArg_ParseTuple(args, "dd", &x, &y);
  return Py_BuildValue("d", x*y);
}

/*
 * Bind Python function names to our C functions
 */
static PyMethodDef myModule_methods[] = {
  {"myFunction", py_myFunction, METH_VARARGS},
  {"myOtherFunction", py_myOtherFunction, METH_VARARGS},
  {NULL, NULL}
};

/*
 * Python calls this to let us initialize our module
 */
void initmyModule()
{
  (void) Py_InitModule("myModule", myModule_methods);
}

Компиляция динамических библиотек в Mac OS X отличается от обычного gcc -расчета, с которым вы могли бы использовать:

gcc -dynamiclib -I/usr/include/python2.3/ -lpython2.3 -o myModule.dylib myModule.c

Теперь вам нужно сделать что-то неловкое; переименуйте myModule.dylib в myModule.so, чтобы Python нашел правильный файл (это ошибка в Python, он должен был быть исправлен, но, насколько мне известно):

mv myModule.dylib myModule.so

Если вы используете систему, которая поддерживает -shared, вы можете просто сделать это:

gcc -shared -I/usr/include/python2.3/ -lpython2.3 -o myModule.so myModule.c

В Windows вы, как сообщается, можете ввести

gcc -shared -IC:\Python27\include -LC:\Python27\libs myModule.c -lpython27 -o myModule.pyd

Здесь простая программа в Python для вызова ваших функций:

from myModule import *

print "Result from myFunction:", myFunction()
print "Result from myOtherFunction(4.0, 5.0):", myOtherFunction(4.0, 5.0)

Вывод:

Result from myFunction(): Hello from C!
Result from myOtherFunction(4.0, 5.0): 20.0

Если вы собираетесь создавать большие библиотеки на Python, я настоятельно рекомендую вам проверить SWIG или Boost Python.