我正在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):
我通过在Py_Initialize();
代码中c
之前添加以下行来解决此问题:
Py_SetPythonHome(L"/PATH/to/python3");
答案 0 :(得分:2)
这可能是因为在Python 3.x
中,模块的初始化不是通过调用init<module_name>
而是通过调用PyInit_<module_name>
来执行的(参见PEP 3121
)。因此,如果您使用Python 3.x
进行链接并通过3.x
执行,则需要更改初始化调用。
简而言之,更改初始化模块的调用:
inittest();
要:
PyInit_test();
并重新编译,应该做的伎俩。
至于您的第二个问题,除了使用Py_SetPythonHome
之外的其他解决方案是在编译之前将PYTHONHOME
设置为python3.4-config --exec-prefix
(或sys.exec_prefix
)的输出。