Run python in C++ -
i have application written in c++ , testing system (also in c++). testing system pretty complicated , hard change (i want make small changes). class looks this:
class derived : public base { public:     void somefunc(const anotherclass& file) { } };   there several functions inside. testing system creates derived class instance , uses it's methods stuff.
now want able write solution in python. need two-way integration. idea write python function, executed every time when somefunc called. , don't want lose variables' values in python 1 launch of function another. , want able use methods defined in base class instance python. how can achieve these things?
i chose boost.python these purposes. now, understand, how use c++ function, or simple class in python after work. don't understand how launch python function c++.
the second question - boost.python choice? need fast and, @ same time, easy use.
thank help.
i recommend using cython sort of thing. adapted examples another question. (edit: upon request, added extended example wraps c++ class, see further below.)
edit: simple example, 1 way (c++ -> python).
quacker.py:
def quack():     print("quack!")   cquacker.pyx:
from quacker import quack  cdef public void cquack():     quack()   main.cpp:
#if _win32 #include <direct.h> #define getcwd _getcwd #define path_separator ';' #else #include <unistd.h> #define path_separator ':' #endif  #include <iostream> #include <string> #include <sstream>  #include <python.h> #include "cquacker.h"  std::wstring getsyspath() {   char cwd[filename_max];   getcwd(cwd, filename_max);   std::wstringstream path;   path << py_getpath() << path_separator << cwd;   return path.str(); }  int main() {   py_initialize();   pysys_setpath(getsyspath().c_str());   pyinit_cquacker();   if (pyerr_occurred())   {     pyerr_print();     return -1;   }   cquack();   py_finalize();   return 0; }   edit: extended example, round trip (c++ -> python -> c++).
quacker.py:
def qcallback(duck):     duck.quack()   quacker/duck.hpp
#include <iostream>  namespace quacker {  class duck { public:     void quack() { std::cout << "quack!" << "\n"; } };  }   cquacker_defs.pxd:
cdef extern "quacker/duck.hpp" namespace "quacker":     cdef cppclass duck:         duck() except +         void quack()   cquacker.pyx:
from cython.operator cimport dereference deref libcpp.memory cimport shared_ptr  cimport cquacker_defs  quacker import qcallback  cdef class duck:     cdef shared_ptr[cquacker_defs.duck] _this      @staticmethod     cdef inline duck _from_this(shared_ptr[cquacker_defs.duck] _this):         cdef duck result = duck.__new__(duck)         result._this = _this         return result      def __init__(self):         self._this.reset(new cquacker_defs.duck())      def quack(self):         assert self._this != null         deref(self._this).quack()   cdef public void cqcallback(shared_ptr[cquacker_defs.duck] duck):     qcallback(duck._from_this(duck))   main.cpp:
#if _win32 #include <direct.h> #define getcwd _getcwd #define path_separator ';' #else #include <unistd.h> #define path_separator ':' #endif  #include <iostream> #include <memory> #include <string> #include <sstream>  #include "quacker/duck.hpp"  #include <python.h> #include "cquacker.h"  std::wstring getsyspath() {   char cwd[filename_max];   getcwd(cwd, filename_max);   std::wstringstream path;   path << py_getpath() << path_separator << cwd;   return path.str(); }  int main() {   py_initialize();   pysys_setpath(getsyspath().c_str());   pyinit_cquacker();   if (pyerr_occurred())   {     pyerr_print();     return -1;   }   auto duck = std::make_shared<quacker::duck>();   cqcallback(duck);   py_finalize();   return 0; }      
Comments
Post a Comment