Python对象到C++指针问题
这是我第一次发帖 :)。我能把一个Python的扩展对象转换成C++的指针,但我遇到了一个问题。首先,我会给你看我的代码,然后再解释这个问题。
这是我的类:
#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";
}
};
Boost封装:
BOOST_PYTHON_MODULE(hello_ext)
{
class_<Base, boost::noncopyable>("Base", no_init);
class_<BaseWrapper, bases<Base> >("BaseWrapper")
.def("HelloWorld", &BaseWrapper::HelloWorld);
}
Python代码(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()
还有主文件:
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;
}
当我运行我的应用程序时,屏幕上会显示“这是一个Hello World!!!”,这正是我期待的结果。
那么,问题出在哪里呢???假设我把Python代码改成:
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()
然后,当我再次运行我的应用程序时,它崩溃了,因为我在这一行出错:
std::cout << base->HelloWorld() << std::endl;
因为base是NULL。
更准确地说,错误是“访问违规,读取位置0xblablabla”。
当我调试时,调试器停在了这个函数(我想是Boost或Python代码)上。
inline api::object_base::~object_base()
{
Py_DECREF(m_ptr);
}
你觉得怎么样???
1 个回答
2
最后,另一个程序员给我解释了这个问题的解决办法。
我不知道最开始为什么会这样,但问题在于对象在我尝试调用它的成员函数之前就被销毁了。我需要把提取的调用分成两部分,像这样:
object derived = module.attr("NewDerived")();
Base* base = extract< Base* >( derived );
这样可以让这个对象保留足够的时间,让我真的能在它上面调用函数。