windows下使用SWIG編譯python模塊

用C++對python加速是個不錯的選擇,但是python直接調用DLL寫起來不是太容易,多虧了SWIG,使這項工作變得簡單。

SWIG官網 

網上對SWIG的使用有些資料,但是直接使用SWIG自帶的example介紹的很少, 雖然官網有Tutorial,但是也有些過時了。爲此寫這篇文章用於記錄使用SWIG例子的步驟,另外還有寫出錯的解決辦法。

使用的環境:

  • PC系統:win10
  • python 3.6 64bit
  • vs2010
  • swigwin-4.0.1

使用例子:\Examples\python\class

步驟:

1、去官網下載Window版SWIGhttp://prdownloads.sourceforge.net/swig/swigwin-4.0.1.zip

2、解壓後,可看到裏面有swig.exe程序。

3、設置環境變量,可參考 swigwin-4.0.1/Doc/Manual/Windows.html,下面是python的設置方法

PYTHON_INCLUDE : Set this to the directory that contains Python.h
PYTHON_LIB : Set this to the Python library including path for linking

Example using Python 2.1.1:
PYTHON_INCLUDE: D:\python21\include
PYTHON_LIB: D:\python21\libs\python21.lib

3、進入例子文件夾下,雙擊直接打開example.dsp(VS2010會將工程升級到新版本)

這裏對工程稍作講解:

工程屬性中,可以看到要用到PYTHON_INCLUDE、PYTHON_LIB環境變量

example.i右擊 =>Custom build Tool => Command Line

可看到 example.i腳本 通過swig.exe程序編譯,運行後會生成example_wrap.cxx和 example.py

4、編譯工程

編譯失敗:報錯信息 c:\python3.6\include\pyport.h(6): fatal error C1083: Cannot open include file: 'inttypes.h': No such file or directory

找到解決方案 https://bugs.python.org/issue29244

Python 3.6 now requires inttypes.h on all platforms.  However, this is not provided by MSVC 2010 and 2012, which is still used by some people who build extension modules for Python.

MSVC 2010 does provide stdint.h, and replacing the inttypes.h include with an include to stdint.h seems to work fine.

I would suggest a fix along the lines of this:

#if defined(_MSC_VER) && _MSC_VER < 1800
#include <stdint.h>
#else
#include <inttypes.h>
#endif

Alternatively, the HAVE_INTTYPES_H definition could be used to fall back to stdint.h, and it could be undefined for the MSVC build.

再次編譯嘗試,報了一堆錯誤

1>     Creating library .\Release\_example.lib and object .\Release\_example.exp
1>example_wrap.obj : error LNK2019: unresolved external symbol __imp__PyUnicode_FromString referenced in function "struct _object * __cdecl SWIG_Python_str_FromChar(char const *)" (?SWIG_Python_str_FromChar@@YAPAU_object@@PBD@Z)
1>example_wrap.obj : error LNK2001: unresolved external symbol __imp__PyExc_RuntimeError
1>example_wrap.obj : error LNK2001: unresolved external symbol __imp__PyExc_AttributeError
1>example_wrap.obj : error LNK2001: unresolved external symbol __imp__PyExc_SystemError
1>example_wrap.obj : error LNK2001: unresolved external symbol __imp__PyExc_ValueError
1>example_wrap.obj : error LNK2001: unresolved external symbol __imp__PyExc_SyntaxError
1>example_wrap.obj : error LNK2001: unresolved external symbol __imp__PyExc_OverflowError
1>example_wrap.obj : error LNK2001: unresolved external symbol __imp__PyExc_ZeroDivisionError
1>example_wrap.obj : error LNK2001: unresolved external symbol __imp__PyExc_TypeError
1>example_wrap.obj : error LNK2001: unresolved external symbol __imp__PyExc_IndexError
1>example_wrap.obj : error LNK2001: unresolved external symbol __imp__PyExc_IOError
1>example_wrap.obj : error LNK2001: unresolved external symbol __imp__PyExc_MemoryError

解決辦法:工程配置成x64 解決,應該是我使用的python是64位的,module設置成x64才能編譯成功

5、測試

runme.py

由於python3版本的緣故,需要修改程序中 print 轉換爲 print()

運行後,打印結果如下:

Creating some objects:
    Created circle <example.Circle; proxy of <Swig Object of type 'Circle *' at 0x000002336E1899C0> >
    Created square <example.Square; proxy of <Swig Object of type 'Square *' at 0x000002336E189A20> >

A total of 2 shapes were created

Here is their current position:
    Circle = (20.000000, 30.000000)
    Square = (-10.000000, 5.000000)

Here are some properties of the shapes:
    <example.Circle; proxy of <Swig Object of type 'Circle *' at 0x000002336E1899C0> >
        area      =  314.1592653589793
        perimeter =  62.83185307179586
    <example.Square; proxy of <Swig Object of type 'Square *' at 0x000002336E189A20> >
        area      =  100.0
        perimeter =  40.0

Guess I'll clean up now
0 shapes remain
Goodbye

祝你好運!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章