python 利用swig 調用c++的接口。

本文所用例子是 swig2.0-examples裏Python的class目錄裏的代碼。python

具體的c++ 代碼以下所示。linux

/* File : example.h */

class Shape {
public:
  Shape() {
    nshapes++;
  }
  virtual ~Shape() {
    nshapes--;
  };
  double  x, y;   
  void    move(double dx, double dy);
  virtual double area(void) = 0;
  virtual double perimeter(void) = 0;
  static  int nshapes;
};

class Circle : public Shape {
private:
  double radius;
public:
  Circle(double r) : radius(r) { };
  virtual double area(void);
  virtual double perimeter(void);
};

class Square : public Shape {
private:
  double width;
public:
  Square(double w) : width(w) { };
  virtual double area(void);
  virtual double perimeter(void);
};


/* 文件名是example.cxx*/
/* File : example.c */

#include "example.h"
#define M_PI 3.14159265358979323846

/* Move the shape to a new location */
void Shape::move(double dx, double dy) {
  x += dx;
  y += dy;
}

int Shape::nshapes = 0;

double Circle::area(void) {
  return M_PI*radius*radius;
}

double Circle::perimeter(void) {
  return 2*M_PI*radius;
}

double Square::area(void) {
  return width*width;
}

double Square::perimeter(void) {
  return 4*width;
}

python接口的文檔以下所示,後綴一般都是python.i.c++

module 對應着具體so的名字。在生成的py文件裏。會import _{module}.so。bash

/* File : example.i */
%module example

%{
#include "example.h"
%}

/* Let's just grab the original header file here */
%include "example.h"

調用 下行命令生成 example_wrap.cxx, 和example.py 文件。python2.7

xxx@xxx-K43SJ:/usr/share/doc/swig2.0-examples/python/class$ sudo swig2.0 -c++ -python example.i

調用以下命令生成example.ossh

sudo g++ -O2 -fPIC -c example.cxx

調用以下命令生成example_wrap.o -I 是用來連接example_wrap.cxx 裏的Python.h的頭文件。ui

若是沒有包含這個頭文件。則apt-get 下個python的dev包。this

sudo g++ -O2 -fPIC -c example_wrap.cxx -I /usr/include/python2.7/

再調用以下命令生成c++ 的so文件。so文件的名字文件對應着.i文件裏的module並且要加_code

sudo g++ -shared *.o -o _example.so

這時候,咱們調用pythonorm

xxx@xxx-K43SJ:/usr/share/doc/swig2.0-examples/python/class$ python
Python 2.7.6 (default, Oct 26 2016, 20:30:19) 
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from example import *
>>> dir()
['Circle', 'Circle_swigregister', 'Shape', 'Shape_swigregister', 'Square', 'Square_swigregister', '__builtins__', '__doc__', '__name__', '__package__', 'cvar']
>>> c = Circle(10)
>>> dir(c)
['__class__', '__del__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__swig_destroy__', '__swig_getmethods__', '__swig_setmethods__', '__weakref__', '_s', 'area', 'move', 'nshapes', 'perimeter', 'this', 'x', 'y']
>>> c.area()
314.1592653589793
>>> c.perimeter()
62.83185307179586
>>> c.nshapes()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>> c.nshapes
1
>>>

 

還有另一種編譯的方式。用distutils來編譯。寫腳本以下,setup.py

#!/usr/bin/env python

"""
setup.py file for SWIG example
"""

from distutils.core import setup, Extension


example_module = Extension('_example',
                           sources=['example_wrap.cxx', 'example.cxx'],
                           )

setup (name = 'example',
       version = '0.1',
       author      = "SWIG Docs",
       description = """Simple swig example from docs""",
       ext_modules = [example_module],
       py_modules = ["example"],
       )

 調用以下命令編譯獲得py文件和so文件。

sudo python setup.py build_ext --inplace

接下來講說編譯多個.cxx或.cpp文件

用g++ 文件的方式編譯連接so時在這個命令裏把其餘.cxx文件也一塊兒編譯成.o,也能夠將*_wrap.cxx一塊兒編譯成.o ,這時候也要添加Python.h的連接路徑。接下來把他們連接成so。就能夠了。

sudo g++ -O2 -fPIC -c *.cxx

第二種方法。

在soureces裏添加其餘要添加的cxx。Extension還能夠添加其餘要連接的so。

example_module = Extension('_example',
                           sources=['example_wrap.cxx', 'example.cxx', 'hello.cxx'],
                           )
相關文章
相關標籤/搜索