在Python中调用C函数

时间:2013-05-20 10:11:39

标签: python c ctypes cython

我有一堆用C编写的函数,我想要一些用Python编写的代码来访问这些函数。

我在这里阅读了几个处理类似问题的问题(例如herehere),但我对我需要采取哪种方法感到困惑。

一个问题推荐ctypes,另一个推荐cython。我已经阅读了两篇文档,我完全不清楚哪一个对我有用。

基本上我已经写了一些python代码来做一些二维FFT,我希望C代码能够看到那个结果然后通过我编写的各种C函数来处理它。我不知道我是否更容易从C调用Python,反之亦然。

4 个答案:

答案 0 :(得分:52)

您应该通过编写 ctypes 包装来从Python调用C. Cython用于使类似python的代码运行得更快,ctypes用于使C函数可以从python调用。您需要做的是:

  1. 编写您要使用的C函数。 (你可能已经这样做了)
  2. 为这些函数创建一个共享对象(.so,用于linux,os x等)或动态加载的库(.dll,用于Windows)。 (也许你已经这样做了)
  3. 编写ctypes包装器(它比听起来更容易,I wrote a how-to for that
  4. 在Python中从该包装器调用一个函数。 (这就像调用任何其他python函数一样简单)

答案 1 :(得分:10)

如果我理解得很好,你就不喜欢对话,因为c => python或类似python => C。 在这种情况下,我会建议Cython。对于多种操作非常开放,特别是在你的情况下,调用一个用C语言编写的函数。

以下是它的工作原理(public api):

以下示例假定您有一个Python类(self是它的一个实例),并且该类有一个方法(名称method),您想要在此类和交易上调用使用C中的结果(此处为double)。此函数以Cython extension编写,可帮助您进行此调用。

cdef public api double cy_call_func_double(object self, char* method, bint *error):
    if (hasattr(self, method)):
        error[0] = 0
        return getattr(self, method)();
    else:
        error[0] = 1

在C方面,您可以像这样执行呼叫:

PyObject *py_obj = ....
...
if (py_obj) {
    int error;
    double result;
    result = cy_call_func_double(py_obj, (char*)"initSimulation", &error);
    cout << "Do something with the result : " << result << endl;
}

其中PyObject是Python / C API提供的struct 抓住py_obj(通过在你的cython扩展中投射常规python object之后:<PyObject *>my_python_object),你最终可以调用initSimulation方法它并对结果做了一些事情。 (这里是double,但Cython可以轻松处理vectors, sets, ...

嗯,我知道如果你从未使用Cython写过任何东西,我刚刚写的东西会让人感到困惑,但它的目的是简短地展示它可以为你做的众多事情。 >合并

另一方面,这种方法比将代码重新编码为C需要更多时间,具体取决于算法的复杂程度。 在我看来,只有当你计划经常有这种需求时,花时间学习Cython是相关的......

希望这至少可以提供信息......

答案 2 :(得分:4)

嗯,这里你指的是两件事。

  1. 如何从python(扩展python)中调用c函数
  2. 如何从C程序(嵌入Python)调用python函数/脚本
  3. #2是'嵌入Python'

    您可以使用以下代码段:

    #include "python.h"
    
    int main(int argc, char *argv[]) {   
    Py_SetProgramName(argv[0]);  /* optional but recommended */   
    Py_Initialize();   
    PyRun_SimpleString("from time import time,ctime\n"
        "print 'Today is',ctime(time())\n");
    /*Or if you want to run python file within from the C code*/       
    //pyRun_SimpleFile("Filename");    
    Py_Finalize();   
    return 0; }
    

    对于'扩展Python' 的#1 那么最好的办法就是使用Ctypes(顺便说一下,所有python变种都是可移植的)。

      
        

    来自ctypes import *

             

    libc = cdll.msvcrt

             

    print libc.time(None)

             

    1438069008

             

    printf = libc.printf

             

    printf(“你好,%s \ n”,“世界!”)

             

    你好,世界!     14

             

    printf(“%d瓶啤酒\ n”,42)

             42瓶啤酒     19

      

    有关详细指南,您可以参考my blog article

答案 3 :(得分:2)

从python调用C会更容易。您的场景听起来很奇怪 - 通常人们在python中编写大部分代码,除了用C编写的处理器密集型部分。二维FFT是代码中计算密集型的部分吗?