C++ダイナミックライブラリをswigでカプセル化する実践


python呼び出しC++には多くのシナリオがあります.swigは使いやすいです.
需要:既存のC++ライブラリa.soとヘッダファイルa.hがpythonでa.soの機能インタフェースを呼び出す方法を仮定します.
最初はa.soのソースコードcppとa.hが必要だと勘違いしていました.実際には,ソースコードは不要であり,swigはヘッダファイルに基づいてpython呼び出し可能なブリッジsoライブラリのコードを自動的に生成することができ,このコードをコンパイルする際にa.soをリンクすれば万事順調であることが分かった.
具体的な実現過程は以下の通りである.
1,swigのxxxを作成する.iプロファイル、例えばmod_a.i ,  
/* File: mod_a.i */
%module mod_a

%{
#include "../a/include/a.h"
%}

%include "../include/a.h"

このファイルには、2つのincludeがあり、最初のincludeは最終的にwrapコードに統合されます.2つ目はswigの入力です.この2つのパスは、主にswig出力のターゲットcxxファイルとmod_に依存して異なることができる.a.i所在ディレクトリ.
2,ブリッジ用のコードをswigで生成する.コマンドを実行できます.
swig -c++ -python mod_a.i

このコマンドが実行されるとmod_a.iが存在するディレクトリの下で2つのファイルを生成する:mod_a.pyとmod_a_wrap.cxx
mod_a.pyはpython呼び出しのためのインタフェースであり、python importのときに自動的に呼び出され、注目する必要はありません. mod_a_wrap.cxxというファイルはブリッジライブラリのc++コードで、このコードを「_mod_a.so」というsoライブラリにコンパイルする必要があります.名前の前に下線が必要ですが、python importはmod_です.a.
3,ブリッジsoライブラリをコンパイルする.ここでは、g++コマンドを使用してコンパイルします.
   g++ -fPIC -shared mod_a_wrap.cxx -o _mod_a.so -I/usr/include/python2.7/ -lpython2.7 -la -L./lib


cmakeで構成することもできます.
cmake_minimum_required(VERSION 2.8.3)
project(a)

set(CMAKE_CXX_FLAGS "-std=c++11 ")
set(DEPEND_LIB_DIR ../dep_lib)
link_directories(    
    ./
    ${DEPEND_LIB_DIR}   
)
include_directories(
    ${DEPEND_LIB_DIR}/include    
    ./include
    /usr/include/python2.7/
)

add_library(a SHARED
   ./src/a.cpp
)

target_link_libraries(a 
    dl
    rt
    pthread
 )

EXECUTE_PROCESS( COMMAND swig -c++ -python -outdir ${PROJECT_BINARY_DIR} -o ${PROJECT_BINARY_DIR}/mod_a_wrap.cxx   ${PROJECT_SOURCE_DIR}/src/mod_a.i  
COMMAND cp  ./src/test_main.py   ${CMAKE_BINARY_DIR}/a/ 
)
message( "output swig py  files to ${PROJECT_BINARY_DIR} ")
message( "output swig cxx files to ${PROJECT_BINARY_DIR}/mod_a_wrap.cxx  ")

add_library(mod_a SHARED
   ${PROJECT_BINARY_DIR}/mod_a_wrap.cxx
)

target_link_libraries(mod_a
    a
    python2.7
 )
 
# OUTPUT_NAME "_mod_a.so"
 set_target_properties(mod_a PROPERTIES PREFIX "_")

ここではbuildとsrcディレクトリを剥離するためにswigの2つのパラメータ-outdirを用いる.pyファイルの出力ディレクトリ、-oはwrapを指定します.cxxファイルの出力パス+名前.
4、最後にpythonでインタフェースを呼び出します.
例:import mod_a 
具体的なテスト例は./src/test_main.py中へ行きます.