第一次用swig,网上找了各种资料,比如
http://www.cnblogs.com/kaituorensheng/p/4464117.html
入门可以看上面这个链接
但要么过于简单要么过于复杂
我的需求是,现在有一个C++工程,包括多个.cpp和.h文件,并且使用了外部的.a .so库
使用python来调用。
假设python需要调用的C++类及其定义都在头文件hello.h中。
首先C++程序自己要能跑通
我们通过swig生成hello.py,并且编译所有.cpp文件,把所使用到的库都链接到hello.py中,然后就可以在python中import hello,使用hello.h中定义的函数和类了
第一步:
编写.i文件
编写hello.i如下
%module hello
%{
#include "hello.h"
%}
%include "hello.h"
运行命令:swig -c++ -python hello.i 生成hello_wrap.cxx
第二步:(这一步是重点)
虽然也可以直接使用gcc编译,但是对于复杂的项目来说,利用distutils来配置并编译简单得多
编写setup.py
from distutils.core import setup, Extension
hello_module = Extension('_hello', #注意这里的名字和下划线,编译你自己的项目时只需要用你的模块名字替换hello就可以了
include_dirs=['./include'], #这一行是指定你的头文件的位置,可以指定多个,用逗号分隔
library_dirs=['./libs'], #这一行定义你的库文件的位置
libraries=['lib1‘,'lib2'], #这一行是重点。如果你的C++中使用了其他.a和.so库,就需要在这里指定,
这些库文件必须在上一行中指定的目录中
sources=['hello_wrap.cxx', 'hello.cpp', 'util.cpp'], #这一行中指定要编译的.cpp文件,必须把第一步中生成的.cxx文件和项目中的所有.cpp文件都加进来
)
setup (name = 'hello', #这里定义一些模块的基本信息
version = '0.1',
author = "SWIG Docs",
description = """Simple swig example from docs""",
ext_modules = [hello_module],
py_modules = ["hello"],
)
编辑完上面的文件后,运行python setup.py build_ext --inplace
编译成功会生成hello.py文件
第三步:
由于使用到了外部的库,要把库文件的位置告诉系统,否则运行时是找不到这些库的
运行export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:库的路径
现在可以试试在python中调用是否成功了
运行python
import hello
h=hello.Hello() #假如hello.cpp中定义了一个类Hello
h.func1(arg1,arg2)
...
补充:
1、如果C++接口参数中带 string或vector,python是识别不了的,需要在.i文件中加入定义
%include "std_string.i"和%include "std_vector.i"
并且说明需要支持的vector元素
例如,需要支持vector
%include "std_vector.i"
namespace std{
%template(intVector) vector
}
相当于声明了一个intVector类,可以在python中使用