5

My main.cpp file looks like this:

// Embeding the interpreter into c++
// https://pybind11.readthedocs.io/en/master/advanced/embedding.html


#include <pybind11/embed.h>
#include <iostream>
#include <string>

// Define namespace for pybind11
namespace py = pybind11;

class Vehiclee
{ 
    // Access specifier 
    public: 

    // Data Members 
    int vehicle_id;
    std::string vehicle_name; 
    std::string vehicle_color;

    // Member Functions() 
    void printname() 
    { 
       std::cout << "Vehicle id is: " << vehicle_id; 
       std::cout << "Vehicle name is: " << vehicle_name; 
       std::cout << "Vehicle color is: " << vehicle_color; 
    } 
}; 


int main() {
    // Initialize the python interpreter
    py::scoped_interpreter python;

    // Import all the functions from scripts by file name in the working directory
    py::module simpleFuncs = py::module::import("simpleFuncs");   

    // Test if C++ objects can be passed into python functions
    Vehiclee car1;
    car1.vehicle_id = 1234;
    car1.vehicle_name = "VehicleName";
    car1.vehicle_color = "red";
    py::object car2 = py::cast(car1);   // <-- PROBLEM
    simpleFuncs.attr("simplePrint")(car2);

    return 0;
}

and I have a simpleFuncs.py:

def simplePrint(argument):
    print(argument)

I'm basically trying to print in python the object and later if possible also the attributes which were defined in C++. The current problem lies in the casting line which cannot cast a C++ object to a Python object. Here i read how to cast back and forth but I get still an error and don't know what to do.

Compilation with make works fine but if I execute it I get this error:

terminate called after throwing an instance of 'pybind11::cast_error'
  what():  make_tuple(): unable to convert argument of type 'object' to Python object
Aborted (core dumped)

If you want to compile and run it yourself here is my CMakeLists.txt:

cmake_minimum_required(VERSION 3.0)
project(wrapper)
add_subdirectory(pybind11)
add_executable(wrapper main.cpp)
target_link_libraries(wrapper PRIVATE pybind11::embed)

Do these steps:

git clone https://github.com/pybind/pybind11
cmake .
make

Thanks in advance.

6
  • i may be talking out of my posterior, but how would you turn a custom class to a python object? i think you either need to add code to tell it how to cast it, or use primitives (again, this is pure conjecture) Commented Jul 9, 2019 at 13:37
  • I'm not sure if it's even possible but here (pybind11.readthedocs.io/en/stable/advanced/pycpp/…) they kinda do it in a pointer way. Commented Jul 9, 2019 at 13:44
  • 2
    some further reading shows that you indeed need to define your own fancy objects like this Commented Jul 9, 2019 at 13:46
  • 1
    have a look at pybind11.readthedocs.io/en/stable/advanced/… Commented Jul 9, 2019 at 14:07
  • @Nullman Can you provide a small example how you would do it for an object? Commented Jul 9, 2019 at 14:35

1 Answer 1

9

You need to add binding code for Vehiclee and import corresponding module.

Note that py::cast call is not necessary

embedded modules doc: https://pybind11.readthedocs.io/en/stable/advanced/embedding.html#adding-embedded-modules

// Embeding the interpreter into c++
// https://pybind11.readthedocs.io/en/master/advanced/embedding.html


#include <pybind11/embed.h>
#include <iostream>
#include <string>

// Define namespace for pybind11
namespace py = pybind11;

class Vehiclee
{
  // Access specifier
public:

  // Data Members
  int vehicle_id;
  std::string vehicle_name;
  std::string vehicle_color;

  // Member Functions()
  void printname()
  {
    std::cout << "Vehicle id is: " << vehicle_id;
    std::cout << "Vehicle name is: " << vehicle_name;
    std::cout << "Vehicle color is: " << vehicle_color;
  }
};

PYBIND11_EMBEDDED_MODULE(embeded, module){

  py::class_<Vehiclee> animal(module, "Vehiclee");
}

int main() {
  // Initialize the python interpreter
  py::scoped_interpreter python;

  // Import all the functions from scripts by file name in the working directory
  auto simpleFuncs = py::module::import("simpleFuncs");
  auto embeded = py::module::import("embeded");


  // Test if C++ objects can be passed into python functions
  Vehiclee car1;
  car1.vehicle_id = 1234;
  car1.vehicle_name = "VehicleName";
  car1.vehicle_color = "red";

  simpleFuncs.attr("simplePrint")(car1);

  return 0;
}

Possible output:

<embeded.Vehiclee object at 0x7f8afb59aa78>
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, I didn't imported and was needed by my surprise... Just a note: it is py::module_::import (missing underscore)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.