User Tools

Site Tools


python:wrapper

This is an old revision of the document!


Passerelle C++/Python

Cette section ne concerne que les développeurs qui souhaitent comprendre la manière dont les fonctionnalités Triskele peuvent être invoquées depuis un programme Python.

L'explication s'appuie sur un exemple d'une fonction et d'une classe écrite en C++. Les codes sources sont dans un répertoire :

drwxr-xr-x 3 4096  build
-rw-r--r-- 1  825  CMakeLists.txt
drwxr-xr-x 2 4096  __pycache__
-rw-r--r-- 1  681  pywrapper.cpp
-rw-r--r-- 1  325  test.cpp
-rw-r--r-- 1  228  test.hpp
-rwxr-xr-x 1  336  test.py
répertoire pour créer les exécutables
Règles de fabrication des binaires
répertoire créé automatiquement par python (accélération)
code passerelle
code C++
interface C++
programme python 

Code C++

L'interface C++ est simple mais couvre plusieurs situations :

  • appel de fonction (hors classe)
  • construction d'un objet
  • surcharge de constructeur
  • accès de variable en lecture/écriture (par valeur et par méthode)
  • invocation de méthode

test.hpp

#include<string>
 
using namespace std;
 
string getMsg ();
 
 
class Mem {
private:
  string msg;
 
public:
  int id;
 
  Mem (string msg);
  Mem (string msg, int id);
  virtual ~Mem ();
 
  void set (string msg);
  string get ();
};

test.cpp

#include <iostream>
 
#include "test.hpp"
 
string
getMsg () {
  cerr << "coucou" << endl;
  return "hello, world";
}
 
Mem::Mem (string msg)
  : Mem (msg, 0) {
}
 
Mem::Mem (string msg, int id)
  : msg (msg), id (id) {
}
 
Mem::~Mem () {
}
 
void
Mem::set (string msg) {
  this->msg = msg;
}
 
string
Mem::get () {
  return msg;
}

Code Python

test.py

#! /usr/bin/python3
 
from libtest import getMsgPy, MemPy
 
print (getMsgPy ())
 
word = MemPy ('A')
word.id = 1;
print (f"m:{word.getPy ()} id:{word.idPy}")
word.setPy ('B')
print (f"m:{word.getPy ()} id:{word.idPy}")
 
word2 = MemPy ('C', 1)
print (f"m:{word2.getPy ()} id:{word2.idPy}")
 
word2.msgPy = word.msgPy+"2"
print (word2.msgPy)

Passerelle

pywrapper.cpp

#include <boost/python.hpp>
 
#include "test.hpp"
 
using namespace boost::python;
 
BOOST_PYTHON_MODULE (libtest) {
  //Py_Initialize ();
 
  def ("getMsgPy", getMsg);
 
  class_<Mem> ("MemPy", init<string>())
    .def (init<string, int>())
    .def ("getPy", &Mem::get)
    .def ("setPy", &Mem::set)
    .def_readwrite ("idPy", &Mem::id)
    .add_property ("msgPy", &Mem::get, &Mem::set)
    ;
}
 
static bool initWrapper () {
  //Py_Initialize ();
  // boost::python::numpy::initialize ();
  return true;
}
static bool isWrapperInit (initWrapper ());

Compilation

cmakelists.txt

cmake_minimum_required (VERSION 3.5)
set (PROJ_NAME "test")
project (${PROJ_NAME})
set (CMAKE_CXX_STANDARD 11)
set (CXX_STANDARD_REQUIRED ON)
set (BUILD_SHARED_LIBS ON)
 
find_package (PythonLibs 3 REQUIRED)
find_package (Boost REQUIRED python3 system chrono)
 
list (APPEND libTestSrc
  "test.cpp"
  "pywrapper.cpp"
  )
 
include_directories (
  PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
  ${Boost_INCLUDE_DIRS}
  ${PYTHON_INCLUDE_DIRS}
  )
 
add_library (test SHARED
  ${libTestSrc}
  )
 
target_link_libraries (test
  ${PYTHON_LIBRARIES}
  ${Boost_LIBRARIES}
  )
mkdir build/
cd build/
cmake ..
make -j $(nproc)
export PYTHONPATH=".:/usr/local/lib/python3/"
../test.py 
coucou
hello, world
m:A id:0
m:B id:0
m:C id:1
B2
python/wrapper.1656167265.txt.gz · Last modified: 2022/06/25 14:27 by francois