【发布时间】:2016-07-20 09:39:05
【问题描述】:
这是我在这里的第一个问题。到目前为止,我得到了很多其他问题的答案,但现在没有答案了。
我工作的目的是使用开发的通信模块堆栈(get as .so),它是用 C 编写的。我想将它与 python(cython)结合起来,因为所有其他软件已经这么写的。在创建并测试了从 cython 到 c 的方向之后,我在最后几天为从 c 到 cython like here 的方向工作。堆栈在 c 函数中对函数进行了事件变化调用,我想集成对 cython 函数的调用以进行日志记录和进一步的数据处理。但是两天后我挂断了。它不起作用,因为 c 函数中的 initmodulename-functioncall 引发了错误。 所以我开发了以下最小的例子来让它在两个方向上工作,cython 和 c。这是this one 的扩展示例。
我有 3 个文件,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-function并回调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-method,但仅适用于 PY_MAJOR_VERSION
提前非常感谢
编辑
我通过删除 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 函数是回调 c 函数,因此有必要在 cython 文件中定义函数 with gil
【问题讨论】: