使用Swig和distutils

时间:2015-09-19 11:51:40

标签: python python-2.7 python-3.x distutils

我已经在C ++中构建了一个应用程序(“Checkyrs”),现在我正在做一些外部工作,它将使用Checkyrs的大部分,但是是用Python 3构建的。(这在我的空闲时间都是这样的,所以它没有“需要成为Python 3,但这是我的偏好。”

要获得python和C ++之间的接口,我正在使用SWIG和python distutils包。我已经构建了一个包含Checkyrs所需内容的动态库,并且我已经使用我提到的工具成功构建了一个Python扩展(“checkyrsai”)。我已经在Python 2.7中测试了它并且它完全可用,我需要的所有C ++类和函数都可以正常运行。

但我的偏好是使用Python 3,虽然我可以使用Python 3构建扩展,但我无法成功加载它:

Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 23 2015, 02:52:03)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import checkyrsai
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/chris/Documents/Programming/eggyolk/checkyrsai.py", line 28, in <module>
    _checkyrsai = swig_import_helper()
  File "/Users/chris/Documents/Programming/eggyolk/checkyrsai.py", line 24, in swig_import_helper
    _mod = imp.load_module('_checkyrsai', fp, pathname, description)
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/imp.py", line 243, in load_module
    return load_dynamic(name, filename, file)
ImportError: dlopen(/Users/chris/Documents/Programming/eggyolk/_checkyrsai.so, 2): Symbol not found: __ZN4Game11ExecuteMoveERKSt6vectorI8PositionSaIS1_EE
  Referenced from: /Users/chris/Documents/Programming/eggyolk/_checkyrsai.so
  Expected in: flat namespace
 in /Users/chris/Documents/Programming/eggyolk/_checkyrsai.so

构建扩展(Python 2)的过程是:

swig -c++ -python checkyrsai.i
python setup.py build_ext --inplace

我的setup.py文件如下所示:

from distutils.core import setup, Extension
import os

os.environ["CC"] = "g++"

checkyrsai = Extension('_checkyrsai',
                    sources = ['checkyrsai_wrap.cxx','../checkyrs/checkyrs/ai.cpp'],
                    include_dirs = ['/usr/local/include','../checkyrs/checkyrs'],
                    libraries = ['Checkyrs'],
                    library_dirs = ['../checkyrs/Build/Products/Release/','/usr/local/lib'],
                    extra_compile_args = ['-std=c++11']
                    )


setup (name = 'checkyrs',
       version = '1.0',
       description = 'checkyrs',
       ext_modules = [checkyrsai])

正如我上面所说,这完美无缺。从这一点开始,我可以打开我的python(2.7)解释器,

import checkyrsai 

然后我去玩我的新玩具。

当尝试为Python 3构建时,我使用几乎完全相同的过程,只需为SWIG添加Python 3标志并通过Python 3运行distutils:

swig -c++ -python -py3 checkyrsai.i
python3 setup.py build_ext --inplace

这会成功运行编译并生成扩展名,但是当我尝试

import checkyrsai

我得到上面引用的ImportError [...]符号未找到问题。

我不会在Python 2和Python 3版本之间以任何方式更改我的代码或setup.py脚本。符号指的是一个应该在我的libCheckyrs.dylib中找到的方法。它显然是可用的,因为它在我使用Python 2.7扩展时成功使用 - 但是当我为Python 3做扩展时似乎找不到它。有没有人有任何建议我哪里出错了?

1 个答案:

答案 0 :(得分:1)

我最终通过更改我链接的C ++库的XCode项目设置来解决这个问题。

具体来说,将“C ++语言方言”设置更改为“C ++ [-std = c ++ 11]”,即我在distutils的extra_compile_args设置中指定的相同版本。以前它是GNU ++ 11,因此符号不匹配,因为命名空间不匹配(std :: vector与std :: __ 1 :: vector)。

通过这种改变,我现在很高兴能够成功地从Python 3中调用我的C ++代码。

我真的不明白为什么中工作在python 2.7中工作,因为它使用了所有相同的distutils设置,指定了相同的C ++版本并且链接到相同的C ++库。如果有人对此有解释,我很乐意听到。