系统:Mac OS 10.12.6。 Python:来自Anoconda3的Python 3.5.2。用Cython == 0.28。
我用
设置并编译了Cython# the .pyx file
from libc.stdint cimport *
cimport CLexActivator
def SetProductFile(filePath):
cdef bytes py_bytes = filePath.encode()
cdef const char* c_string = py_bytes
cdef int32_t status = CLexActivator.SetProductFile(c_string)
print(status)
return status
和
# the setup file
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
ext_modules=[
Extension("PyLexActivator",
sources=["PyLexActivator.pyx"],
language='c',
extra_objects=["libLexActivator.a"],
)
]
setup(
name = "PyLexActivator",
ext_modules = cythonize(ext_modules)
)
我使用python setup.py build_ext --inplace
进行编译。
Compiling PyLexActivator.pyx because it changed.
[1/1] Cythonizing PyLexActivator.pyx
running build_ext
building 'PyLexActivator' extension
creating build
creating build/temp.macosx-10.6-x86_64-3.5
/usr/bin/clang -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Users/o/anaconda/include -arch x86_64 -I. -I/Users/o/anaconda/include/python3.5m -c PyLexActivator.c -o
build/temp.macosx-10.6-x86_64-3.5/PyLexActivator.o
/usr/bin/clang -bundle -undefined dynamic_lookup -L/Users/o/anaconda/lib -arch x86_64 build/temp.macosx-10.6-x86_64-3.5/PyLexActivator.o libLexActivator.a -L/Users/o/anaconda/lib -o /path to/PyLexActivator.cpython-35m-darwin.so
运行import PyLexActivator
dlopen(/path to/PyLexActivator.cpython-35m-darwin.so, 2):
Symbol not found: __ZNSs4_Rep20_S_empty_rep_storageE
Referenced from: /path to/PyLexActivator.cpython-35m-darwin.so
Expected in: flat namespace
in /path to/PyLexActivator.cpython-35m-darwin.so
我不知道__ZNSs4_Rep20_S_empty_rep_storageE
代表什么。由于.pyx
使用静态库libLexActivator.a
编译,我猜这个错误可能来自未知的引用。但我不知道如何解决它。
我还使用otool -L
来显示
PyLexActivator.cpython-35m-darwin.so:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)
PS:如果我使用language="c++"
,则会出现另一个错误Symbol not found: _kSCPropNetProxiesHTTPPort
。
答案 0 :(得分:1)
首先,缺少的函数是C ++错位名称。现在大多数编译器都带有解码工具,或者你可以使用像this one这样的在线解码器,它适用于所有非古老版本的clang ++,g ++和MSVC。结果是_std::string::_Rep::_S_empty_rep_storage
。
这显然是C ++标准库的一部分。问题是您编译了一些代码以使用C ++ std::string
,但没有链接C ++ stdlib。这不是你的Cython生成的代码或Python,所以可能是libLexActivator.a
。
通过在language="c++"
电话中添加cythonize
,可以轻松解决此问题。have Cython compile all of your code as C++ instead of C。这比你需要的更加极端,但它可能很好。
或者,你可以选择正确的C ++ stdlib并链接到那个。这对Mac上的clang来说有点混乱,因为有两个,libc++
和libstdc++
。最新版本默认为前者(libc++
是一个较新的实现,由LLVM / Clang团队构建,可以更好地与C ++ 11及更高版本配合使用)。但如果你的建造时间为10.6,我不确定这是否仍然正确。所以你可能需要研究它(或者询问有关C ++,Mac和Clang相关标签的专家),或者只是尝试两种并看看。
根据您的评论,修复后,您会看到另一个缺失的符号_kSCPropNetProxiesHTTPPort
。这种与众不同的命名风格几乎可以肯定意味着它是由Apple的CoreFoundation
框架内部或者其他C框架之一导出的常量导出的。但不要猜测,只需将其粘贴到您最喜爱的搜索引擎中,您就会找到the docs,这表明它是SystemConfiguration
框架的一部分。因此,您还需要将其添加到构建中。
此时,很明显libLexActivator.a
不仅仅是简单的C / POSIX代码;它有一些平台依赖(并且它可能也有第三方依赖,对于我所知道的所有)它需要链接。因此,最好的办法是找到它的文档,看看它与它的链接需要什么。 (如果没有这样的文档,你应该能够从Makefile
和/或其他构建工具中找到它,但如果你不知道怎么做,你应该真的问一个单独标记的C ++问题帮助。)