All of these files should be placed in one directory.
mkdir build && cd build
cmake ..
makecd ..
python3 ./load_libs.py| #include <boost/python.hpp> | |
| #include <boost/python/raw_function.hpp> | |
| #include "CppClasses.hpp" | |
| namespace python = boost::python; | |
| // Converter needed for handling vectors (or lists) returned by C++ methods | |
| template <class T> struct VecToList | |
| { | |
| static PyObject *convert(const std::vector<T> &vec) | |
| { | |
| boost::python::list *l = new boost::python::list(); | |
| for (auto &&i : vec) | |
| { | |
| l->append(i); | |
| } | |
| return l->ptr(); | |
| } | |
| }; | |
| //Raw cpp function | |
| char const* greeter(){ | |
| return "hello World! from outside class"; | |
| }; | |
| std::vector<int> get_list() | |
| { | |
| std::vector<int> v; | |
| v.push_back(1); | |
| v.push_back(2); | |
| return v; | |
| } | |
| //Boost.Python wrapper defining the module name, classes and methods | |
| BOOST_PYTHON_MODULE(bindings){ | |
| python::class_<Hello>("Hello") | |
| //.def(init<double, double>()) //another constructor if needed | |
| .def("greet",&Hello::greet) //simple methods | |
| .def("set",&Hello::set) | |
| //.def_readonly("len", &Hello::len) //access to class fields | |
| .def_readwrite("len", &Hello::len) | |
| ; | |
| python::class_<Class2>("Class2",python::no_init) | |
| .def(python::init<int>()); | |
| python::def("print_hello", greeter); | |
| python::def("get_list", get_list); | |
| //using lists returned by C++ needs defining converter handling this type of variable | |
| python::to_python_converter<std::vector<int, std::allocator<int>>, VecToList<int>>(); | |
| } |
| cmake_minimum_required(VERSION 3.5) | |
| project(cpp_to_pyt_bindings) | |
| # Find python and Boost - both are required dependencies | |
| find_package(PythonLibs 3.5 REQUIRED) | |
| find_package(Boost COMPONENTS python REQUIRED) | |
| # Without this, any build libraries automatically have names "lib{x}.so" | |
| set(CMAKE_SHARED_MODULE_PREFIX "") | |
| file(GLOB_RECURSE HEADERS ${CMAKE_SOURCE_DIR} "*.hpp") | |
| file(GLOB_RECURSE SOURCES ${CMAKE_SOURCE_DIR} "*.cpp") | |
| include_directories( | |
| ${CMAKE_HOME_DIRECTORY}/include | |
| ) | |
| # Add a shared module - modules are intended to be imported at runtime. | |
| # - This is where you add the source files | |
| add_library(bindings MODULE ${HEADERS} ${SOURCES} ) | |
| # Set up the libraries and header search paths for this target | |
| target_link_libraries(bindings ${Boost_LIBRARIES} ${PYTHON_LIBRARIES}) | |
| target_include_directories(bindings PRIVATE ${PYTHON_INCLUDE_DIRS}) |
| #include <string> | |
| #include <iostream> | |
| //example of class without default constructor | |
| class Class2{ | |
| public: | |
| Class2(int number){}; | |
| }; | |
| class Hello{ | |
| private: | |
| std::string msg; | |
| public: | |
| std::string greet(){ | |
| std::cout << "Hello World!\n"; | |
| return msg; | |
| } | |
| //Set the message string | |
| void set(std::string text){ | |
| this->msg = text; | |
| } | |
| int len; //public data member | |
| }; |
| #!/usr/bin/python3 | |
| import os | |
| import sys | |
| module_path = os.path.dirname(os.path.realpath(__file__)) + "/build/" | |
| sys.path.append(module_path) | |
| try: | |
| from bindings import * | |
| print("Library imported") | |
| except: | |
| print("Something went wrong during import") | |
| print("__file__ : " + __file__) | |
| print("sys.path: " + str(sys.path)) | |
| print_hello() | |
| get_list() | |
| h = Hello() | |
| h.set("Hi") | |
| h.greet() | |
| h.len = 50 | |
| print("h.len: ", h.len) | |
| c2 = Class2(88) |
Expected result:
Library imported
Hello World!
h.len: 50