从Python调用C函数(无返回值)

12

我使用SWIG将我的C++程序与Python连接起来。从cFunctions.py中,我像下面这样调用名为checkValC函数:

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中访问)。问题是,当我从我的测试代码中调用“check”(cFunctions.check(10,20))时,我能够执行它,但它却从未返回任何东西!

但如果我像这样从cFunctions.py内部调用check

check(10,Trx.a2)

它返回结果。我做错了什么?为什么当我从test.py调用时check没有返回任何东西?


1
嗯,我不确定。在你的check定义中,lib.checkVal(a2,a3,Trx.a4...)的前两个参数被调用时没有使用Trx引用。也许在cFunctions.py中a2和a3被正确定义了,但在测试代码中没有。此外,你从未使用过kulTrxType,这是有意为之吗? - Bort
谢谢@Bort,这是一个好观点,我会尝试一下。另外,我已经编辑了我的问题,针对kulTrxType。 - AJ-B29
1个回答

1

这个有用吗?我通过一些谷歌搜索找到了这里!

从Python调用C函数 - 作者:Christian Stigen Larsen

为了参考,将以上链接复制在此处。 我没有测试这里列出的代码。所有的功劳都归原作者所有。

这是一个关于如何从Python中调用你的C函数的小教程。

让我们在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 -shared有所不同:
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中使用,我强烈建议你查看SWIGBoost Python

1
那应该是一条注释,而不是一个答案。 - ForceBru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接