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