Python object for C ++ pointer task

This is my first post :). I could convert the extended python object to a C ++ pointer, but I have a problem. I will show you my code first, and then I will explain the problem.

This is my class:

#include <boost/python.hpp> using namespace boost::python; class Base { public: virtual const char* HelloWorld() = 0; }; class BaseWrapper : public Base, public wrapper<BaseWrapper> { public: virtual const char* HelloWorld() { if (override f = this->get_override("HelloWorld")) return call<const char*>(f.ptr()); return "FAILED TO CALL"; } }; 

Pack acceleration:

 BOOST_PYTHON_MODULE(hello_ext) { class_<Base, boost::noncopyable>("Base", no_init); class_<BaseWrapper, bases<Base> >("BaseWrapper") .def("HelloWorld", &BaseWrapper::HelloWorld); } 

Python Code (hello.py):

 def NewDerived(): import hello_ext class Derived(hello_ext.BaseWrapper): def __init__(self): super(Derived, self).__init__() def HelloWorld(self): return "This is a Hello World!!!" return Derived() 

and main file:

 int main() { // Start the interpreter. Py_Initialize(); // Import the module that we need (hello.py) object module = import("hello"); // Get a C++ pointer of the derived python class. Base* base = extract< Base* >( module.attr("NewDerived")() ); // Call the HelloWorld function std::cout << base->HelloWorld() << std::endl; } 

When I launch my application, I see on the screen "This is Hello World !!!" as I expected. So what's the problem??? Suppose I change python code to:

 def NewDerived(): import hello_ext class Derived(hello_ext.BaseWrapper): def __init__(self): super(Derived, self).__init__() def HelloWorld(self): return "This is a Hello" # I CHANGED THIS LINE!!!! return Derived() 

Then, when I run my application again, it crashes because I received an error in the line:

 std::cout << base->HelloWorld() << std::endl; 

because base is NULL.

More precisely, the error is: "0xblablabla Access Violation Detection Location". When I debug, debugguer stops in a function (e.g. Boost or Python code)

 inline api::object_base::~object_base() { Py_DECREF(m_ptr); } 

What do you think???

+4
source share
1 answer

Finally, another programmer explained the solution to me.

I don’t know why this worked initially, but the problem is that the object is destroyed before I try to call the member function. I need to split the extraction call into two parts:

 object derived = module.attr("NewDerived")(); Base* base = extract< Base* >( derived ); 

This will save the object long enough so that I can actually name it.

+2
source

Source: https://habr.com/ru/post/1335576/


All Articles