【问题标题】:Calling C function from Python (No Return Value)从 Python 调用 C 函数(无返回值)
【发布时间】:2015-04-28 14:55:43
【问题描述】:

我使用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 访问)。问题是,当我从我的测试代码(cFunctions.check(10,20))中调用“check”时,我到达了它,但它永远不会返回任何东西!

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

check(10,Trx.a2)

它返回结果。我究竟做错了什么?为什么当我从 test.py 调用它时 check 不返回任何内容?

【问题讨论】:

  • 嗯我不确定。在check 的定义中,lib.checkVal(a2,a3,Trx.a4... 的前两个参数在没有 Trx 引用的情况下被调用。也许在 cFunctions.py 中,a2 和 a3 被正确定义,但在测试代码中没有。你也从来不使用kulTrxType 这是故意的吗?
  • 谢谢@Bort,这是一个很好的观点,我要试试这个。另外我已经编辑了我的 kulTrxType 问题。

标签: python c swig


【解决方案1】:

这有帮助吗?一点谷歌搜索把我带到了这里!

Calling C functions from Python - By 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

【讨论】:

  • 最好是评论,而不是答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-24
  • 1970-01-01
  • 2014-11-23
  • 2021-10-17
  • 1970-01-01
  • 2022-07-21
相关资源
最近更新 更多