簡體   English   中英

使用 Swig 和 distutils 為 Python 3 構建擴展

[英]building extension for Python 3 with Swig and 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 [...] Symbol not found 問題。

我不會在 Python 2 和 Python 3 版本之間以任何方式更改我的代碼或 setup.py 腳本。 該符號指的是應該在我的 libCheckyrs.dylib 中找到的方法。 它顯然在那里可用,因為當我使用 Python 2.7 擴展時它被成功使用 - 但是當我為 Python 3 制作擴展時似乎沒有找到它。有人對我哪里出錯有什么建議嗎?

我最終通過更改我鏈接的 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 ++ lib中的鏈接。 如果有人對此有解釋,我很樂意聽到。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM