我正在尝试使用Cython从python生成c代码,但似乎存在名称修改的一些问题。我首先生成将代码从python转换为c代码,然后使用gcc将代码编译成.so。我想使用cython而不是C / python API的原因是因为我稍后会在更复杂的类上使用它,我希望以后成为一个速度等的库(我很难找到去的人从python到C ++,因为它通常是相反的方式)。下面是我必须尝试执行代码的所有代码(但都失败了)。任何输入将不胜感激。谢谢!
#hello.pyx
def say_hello():
print "Hello World!"
#generate the c code
cython -a hello.pyx
#creates the shared library
gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python2.6 -o libhello.so hello.c
//temp.cpp
#include <iostream>
extern "C" {
void say_hello();
};
using namespace std;
int main(){
say_hello();
return 1;
};
#attempt to compile (this is where it fails)
g++ -I/usr/include/python2.6/ -lpython2.6 -L./ -lhello temp.cpp -o temp
以下是错误消息:
/tmp/ccpKHOMl.o: In function main: temp.cpp:(.text+0x5): undefined reference to say_hello' /tmp/ccpKHOMl.o:
In function __static_initialization_and_destruction_0(int, int):
temp.cpp:(.text+0x33): undefined reference to std::ios_base::Init::Init()
temp.cpp:(.text+0x38): undefined reference to std::ios_base::Init::~Init()
collect2: ld returned 1 exit status
答案 0 :(得分:3)
您无法以这种方式获得所需的互操作性。如果打开并检查hello.c,那么在那里的任何地方都找不到“static int say_hello”。 Cython旨在让Python使用C库,而不是让C库使用python。
您可以在文档中查看,但不幸的是,这种支持仍然是一个“负责”的python解释器,而您正在寻找的是另一种方式。
http://docs.python.org/release/2.5.4/ext/callingPython.html
还有关于“在另一个应用程序中嵌入Python”的入门知识
http://docs.python.org/2/extending/embedding.html
我不知道你的要求是什么,但在某些情况下你可以成功地将数据写入文件,调用Python程序来咀嚼它,然后从另一个文件解析结果。它比记忆中的内容有点丑陋和慢,但在许多情况下它完全可行。
答案 1 :(得分:1)
我遇到了类似的问题。这不是完全相同的问题,但它可能是相关的。
我在这里发布了我的问题:Propagating exceptions through dlsym cython。有趣的部分是'public'关键字:
#hello.pyx
cdef public say_hello():
print "Hello World!"
这将创建一个像这样的函数
# (in the generated C file hello.c)
__PYX_EXTERN_C DL_IMPORT(...) say_hello(...);
编辑:我添加了一个有效的temp.cpp:
#include "Python.h"
#include <iostream>
#include "hello.h"
using namespace std;
int main(){
Py_Initialize();
inithello();
say_hello();
Py_Finalize();
return 1;
};
编译完成:
g++ -I/usr/include/python2.6/ -lpython2.6 -L./ -lhello temp.cpp -c -o temp.o
g++ temp.o -L. -lhello -lpython2.6 -o temp
(有趣的是,它不会在一步中链接,抱怨未定义的引用。) 这将在执行时成功打印“Hello world”。
注意:Py_Initialize()和inithello()是必需的,否则您的代码将崩溃。如果没有包含“Python.h”并且没有初始化部分(即仅使用extern“C”{void sayhello();}),我无法使其工作。它在链接时失败了。解决方案可以是使用dlsym并动态加载你的函数,正如我在我的问题中演示的那样。但是可能存在另一种解决方案,您尝试成功导出此方法(在hello.h头文件中): __PYX_EXTERN_C DL_IMPORT(int)say_hello(void);
答案 2 :(得分:0)
如果您有CMake,我建议您查看我的项目,我使用CMake生成并链接基于Cython的文件
https://github.com/CarloNicolini/cymake
您可能需要编辑一些CMakeLists.txt以找到正确的cython安装