Cython Compile Error: Python3 Compatibility
Cython Compile Error: Python3 Compatibility
我 运行宁 Python 3.4.4 :: Anaconda 4.0.0 (x86_64)
OS X Yosemite
。我的 Cython 版本是 0.23.4
。我正在尝试将一些非常简单的 Cython 代码 test.pyx
嵌入到 C 代码 testcc.c
中。问题是,如果我使用 python2.7-config
那么一切正常(Python 2.7 是 OS X 上的内置版本)。但是,如果我使用 python3.4-config
,则会出现以下错误:
Undefined symbols for architecture x86_64:
"_inittest", referenced from:
_main in testcc-b22dcf.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我必须使用 Python3,因为我所有的其他代码都写在里面。请帮我解决这个问题。
以下是我的源文件:
test.pyx
:
cdef public void pythonAdd(int[] a):
a[1] = 5
a[0] = 4
testcc.c
:
#include "Python.h"
#include "test.h"
#include <math.h>
#include <stdio.h>
int main(int argc, char **argv) {
Py_Initialize();
inittest();
int a [2] = {0 , 0};
pythonAdd(a);
printf("fist: %d, second: %d", a[0], a[1]);
Py_Finalize();
return 0;
}
并使用以下 setup.py
:
编译这两个文件
from distutils.core import setup, Extension
from Cython.Build import cythonize
ext = Extension("testc", sources=["test.pyx"])
setup(name="testc", ext_modules=cythonize(ext))
下面是我编译那些c文件的命令:
ldflags:=$(shell $(python3.4-config) --ldflags)
cflags:=$(shell $(python3.4-config) --cflags)
python setup.py build_ext --inplace
cython test.pyx
gcc $(cflags) $(ldflags) test.c testcc.c -o cysvm.out
更新:
我按照 Jim 的建议将 inittest()
更改为 PyInit_test()
。代码编译成功。但是,当我 运行 ./cysvm.out
时,出现了以下错误:
./cysvm.out
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
Fatal Python error: Py_Initialize: unable to load the file system codec
ImportError: No module named 'encodings'
Current thread 0x00007fff772f5300 (most recent call first):
更新
我通过在 c
代码中的 Py_Initialize();
之前添加以下行解决了这个问题:
Py_SetPythonHome(L"/PATH/to/python3");
这可能是因为在 Python 3.x
中,模块的初始化不是通过调用 init<module_name>
而是通过 PyInit_<module_name>
执行的(参见 PEP 3121
).因此,如果您链接 Python 3.x
并通过 3.x
执行,您需要更改初始化调用。
简而言之,将初始化模块的调用更改为:
inittest();
收件人:
PyInit_test();
然后重新编译,应该可以解决问题。
至于你的第二个问题,除了使用 Py_SetPythonHome
之外的替代解决方案是在编译之前设置 PYTHONHOME
to the output of python3.4-config --exec-prefix
(or sys.exec_prefix
)。
我 运行宁 Python 3.4.4 :: Anaconda 4.0.0 (x86_64)
OS X Yosemite
。我的 Cython 版本是 0.23.4
。我正在尝试将一些非常简单的 Cython 代码 test.pyx
嵌入到 C 代码 testcc.c
中。问题是,如果我使用 python2.7-config
那么一切正常(Python 2.7 是 OS X 上的内置版本)。但是,如果我使用 python3.4-config
,则会出现以下错误:
Undefined symbols for architecture x86_64:
"_inittest", referenced from:
_main in testcc-b22dcf.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我必须使用 Python3,因为我所有的其他代码都写在里面。请帮我解决这个问题。
以下是我的源文件:
test.pyx
:
cdef public void pythonAdd(int[] a):
a[1] = 5
a[0] = 4
testcc.c
:
#include "Python.h"
#include "test.h"
#include <math.h>
#include <stdio.h>
int main(int argc, char **argv) {
Py_Initialize();
inittest();
int a [2] = {0 , 0};
pythonAdd(a);
printf("fist: %d, second: %d", a[0], a[1]);
Py_Finalize();
return 0;
}
并使用以下 setup.py
:
from distutils.core import setup, Extension
from Cython.Build import cythonize
ext = Extension("testc", sources=["test.pyx"])
setup(name="testc", ext_modules=cythonize(ext))
下面是我编译那些c文件的命令:
ldflags:=$(shell $(python3.4-config) --ldflags)
cflags:=$(shell $(python3.4-config) --cflags)
python setup.py build_ext --inplace
cython test.pyx
gcc $(cflags) $(ldflags) test.c testcc.c -o cysvm.out
更新:
我按照 Jim 的建议将 inittest()
更改为 PyInit_test()
。代码编译成功。但是,当我 运行 ./cysvm.out
时,出现了以下错误:
./cysvm.out
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
Fatal Python error: Py_Initialize: unable to load the file system codec
ImportError: No module named 'encodings'
Current thread 0x00007fff772f5300 (most recent call first):
更新
我通过在 c
代码中的 Py_Initialize();
之前添加以下行解决了这个问题:
Py_SetPythonHome(L"/PATH/to/python3");
这可能是因为在 Python 3.x
中,模块的初始化不是通过调用 init<module_name>
而是通过 PyInit_<module_name>
执行的(参见 PEP 3121
).因此,如果您链接 Python 3.x
并通过 3.x
执行,您需要更改初始化调用。
简而言之,将初始化模块的调用更改为:
inittest();
收件人:
PyInit_test();
然后重新编译,应该可以解决问题。
至于你的第二个问题,除了使用 Py_SetPythonHome
之外的替代解决方案是在编译之前设置 PYTHONHOME
to the output of python3.4-config --exec-prefix
(or sys.exec_prefix
)。