TypeError: No to_python (by-value) converter found for C++ type

2024/10/14 19:28:30

I'm trying to expose my C++ Classes to Python using Boost.Python. Here is a simplyfied version of what I'm trying to do:

struct Base {virtual ~Base() {};virtual char const *Hello() {printf("Base.Hello\n");return "Hello. I'm Base.";};
};struct Derived : Base {char const *Hello() {printf("Derived.Hello\n");return "Hello. I'm Derived.";};Base &test() {printf("Derived.test\n");// ...// After some calculation, we get result reference `instance'// `instance' can be an instance of Base or Derived.// ...return instance;}
};

I want to use above classes as follows in python:

instance = Derived()// If method test returns an instance of Base
instance.test().Hello() // Result: "Hello. I'm Base."// If method test returns an instance of Derived
instance.test().Hello() // Result: "Hello. I'm Derived."

I didn't know any nice solution to this problem. I just tried this:

struct BaseWrapper : Base, wrapper<Base> {char const *Hello() {printf("BaseWrapper.Hello\n");if (override Hello = this->get_override("Hello")) {return Hello();}return Base::Hello();}char const *default_Hello() {printf("BaseWrapper.default_Hello\n");return this->Base::Hello();}
};struct DerivedWrapper : Derived, wrapper<Derived> {char const *Hello() {printf("DerivedWrapper.Hello\n");if (override Hello = this->get_override("Hello")) {return Hello();}return Derived::Hello();}char const *default_Hello() {printf("DerivedWrapper.default_Hello\n");return this->Derived::Hello();}Base &test() {printf("DerivedWrapper.test\n");if (override Hello = this->get_override("test")) {return Hello();}return Derived::test();}Base &default_test() {printf("DerivedWrapper.default_test\n");return this->Derived::test();}
};

And them, I use following code:

BOOST_PYTHON_MODULE(Wrapper) {class_<BaseWrapper, boost::noncopyable>("Base").def("Hello", &Base::Hello, &BaseWrapper::default_Hello);class_<DerivedWrapper, boost::noncopyable, bases<Base> >("Derived").def("Hello", &Derived::Hello, &DerivedWrapper::default_Hello).def("test", &Derived::test,  return_value_policy<copy_non_const_reference>());
}

But when I compiled above code into a .so file, and used in python

derived = Wrapper.Derived() 
derived.test()

It throws out an exception:

TypeError: No to_python (by-value) converter found for C++ type: Base
  1. This post has the same error as mine, but in a different way, it didn't help me a lot. Boost.Python call by reference : TypeError: No to_python (by-value) converter found for C++ type:

  2. This post solves a similar problem, but didn't help me either. https://github.com/BVLC/caffe/issues/3494

I have two problems:

  1. If the way I tried is the right way, how to solve the TypeError problem?
  2. If I tried a wrong way, then what is the best way to solve the problem using boost.python?
Answer

This code works for me:

struct Base {virtual ~Base() {};virtual char const *hello() {return "Hello. I'm Base.";};
};struct Derived : Base {char const *hello() {return "Hello. I'm Derived.";};Base &test(bool derived) {static Base b;static Derived d;if (derived) {return d;} else {return b;}}
};BOOST_PYTHON_MODULE(wrapper)
{using namespace boost::python;class_<Base>("Base").def("hello", &Base::hello);class_<Derived, bases<Base>>("Derived").def("test", &Derived::test, return_internal_reference<>());
}

Testing module:

>>> import wrapper
>>> d = wrapper.Derived()
>>> d.test(True).hello()
"Hello. I'm Derived."
>>> d.test(False).hello()
"Hello. I'm Base."
>>>
https://en.xdnf.cn/q/117923.html

Related Q&A

USB interface in Python

I have this (http://www.gesytec.de/en/download/easylon/p/16/) USB device connected to my Win7. I am just trying to read the vendor ID and product ID. I have Python 2.7.Here is the code,import usb busse…

Django M2M Through extra fields with multiple models

Im trying to figure out the best way to set up the following django model (genericised for security reasons).ThingA:User(M2M through "UserRelation")ThingB:User(M2M through "UserRelation&…

Openpyxl: Worksheet object has no attribute values

My goal is to read in an excel file and view the codes in a pandas dataframe (i.e. = A3) rather than the resulting values from excel executing the codes, which is the pandas default if read in using pa…

Calculation of Contact/Coordination number with Periodic Boundary Conditions

I have data for N atoms including the radius of each atom, the position of each atom and the box dimensions. I want to calculate the number of atoms each atom is in contact with and store the result. T…

how can I export multiple images using zipfile and urllib2

I am trying to add multiple image files into my zip. I have searched around and knows how to add a single one. I tried to loop through multiple images then write into it but it didnt work. I kind of d…

XPATH for Scrapy

So i am using SCRAPY to scrape off the books of a website. I have the crawler working and it crawls fine, but when it comes to cleaning the HTML using the select in XPATH it is kinda not working out ri…

Kivy Removing elements from a Stack- / GridLayout

I made a pop-up. It is basically some rows of options (max. 5 rows).If I press the + button, there will be a new line of options.If I press the - button the last row should diasappear. Unfortunatelly i…

Bad timing when playing audio files with PyGame

When I play a sound every 0.5 second with PyGame:import pygame, timepygame.mixer.init() s = pygame.mixer.Sound("2.wav")for i in range(8):pygame.mixer.Channel(i).play(s)time.sleep(0.5)it doesn…

Using read_batch_record_features with an Estimator

(Im using tensorflow 1.0 and Python 2.7)Im having trouble getting an Estimator to work with queues. Indeed, if I use the deprecated SKCompat interface with custom data files and a given batch size, the…

How to insert integers into a list without indexing using python?

I am trying to insert values 0 - 9 into a list without indexing. For example if I have the list [4, 6, X, 9, 0, 1, 5, 7] I need to be able to insert the integers 0 - 9 into the placeholder X and test i…