使用来自c

时间:2016-07-20 09:39:05

标签: python cython

这是我的第一个问题。到目前为止,我通过其他问题得到了很多答案,但现在没有更多答案了。

我的工作目标是使用已开发的通信模块堆栈(get as .so),这是用C语言编写的。我想将它与python(cython)结合使用,因为所有其他软件已经是这样写的。在创建和测试从cython到c的方向之后,我在最后几天工作,从c到cython like here。堆栈在c函数中对函数进行了event-driffen调用,我希望集成一个cython函数调用来进行日志记录和进一步的数据处理。但两天后我挂断了电话。它不起作用,因为c函数中的initmodulename-functioncall引发了错误。 所以我开发了以下最小的例子来使它工作,cython和c在两个方向上。这是this one的扩展示例。

我有3个文件, the main.c

#include <python3.4/Python.h>
#include "caller.h"
int main() {
Py_Initialize();
initcaller();
call_quack();
Py_Finalize();
return 0;
}

caller.pyx

from quacker import quack

cdef public void call_quack():
    quack()

def run():
    cdef extern from "main.c":
        int main()
    main()

quacker.py

def quack():
    print("Quack!")

目标是导入调用者,启动run()作为函数,调用c函数并调用call_quack()。

编译我使用(这来自主项目):

CC="gcc -std=c99" CFLAGS="-DCPLB_VENDOR_EAG_TARGETSYSTEM_SHLIBSIEC104_ARM_LINUX -O2 -fPIC"  IFLAGS="-I/usr/include/python3.4 -lpython3.4"  python3.4 setup.py build_ext --inplace 

使用setup.py

 # setup.py file
 import sys
 import os
 import shutil
 from distutils.core import setup
 from distutils.extension import Extension
 from Cython.Distutils import build_ext


setup(
cmdclass = {'build_ext': build_ext},
ext_modules = [
    Extension("caller", 
              sources=["caller.pyx",
                       ],
              include_dirs=["/usr/include//python3.4"],
              extra_compile_args=["-fopenmp", "-O3"],
              extra_link_args=["-DSOME_DEFINE_OPT", 
                               "-L./some/extra/dependency/dir/"]
         )
    ]
    )    

编译和链接期间没有错误。 但是当我启动python3.4并导入调用者时,我收到以下错误

ImportError: /home/rvk/software/test/caller.cpython-34m.so: undefined symbol: initcaller

任何人都可以帮我解决这个问题吗?我从来没有在两个方向上读过关于usind cython和c的任何例子!有可能吗?

我已经检查过cythonized c-File(caller.c) - 有一个initcaller方法,但只适用于PY_MAJOR_VERSION&lt; 3?!

提前多多感谢

修改

我通过删除 main.c 中的PyInitialze,initcaller和PyFinalize - 函数调用来实现它。也许这与问题有关,我已经在pyx中声明了main.c,所以它是编译库的一部分?!不知道泄漏涉及的地方cython user guide

新的main.c:

#include <python3.4/Python.h>
#include "caller.h"
int main() {
call_quack();
return 0;
}

我还将它整合到主项目中。这里面临的挑战是,应该在cython文件中调用函数的c函数是一个回调函数,所以有必要在cython文件中定义函数 with gil

1 个答案:

答案 0 :(得分:1)

caller.pyx中有

def run():
    cdef extern from "main.c":
        int main()
    main()

通过包含main.c导致问题,而caller.h又包含main(),这是由cython生成的代码意外发生的事情。此外,调用main.c中定义的cdef extern from "main.c":可能会在python解释器中发生时遇到麻烦。因此应删除PyInit_modulename()

对于python 3.x,它就像initmodule(),而不是int main() { Py_Initialize(); PyInit_caller(); call_quack(); Py_Finalize(); return 0; }

A instA = new A();
instA.setImage(*image)