C++/Boost Python类重写

2024-06-07 04:31:45 发布

您现在位置:Python中文网/ 问答频道 /正文

好吧。我的问题其实很简单。这是一个frame listener类和python包装器类,boost python将使用它:

class FrameListener
    {
    public:

        struct FrameEvent
        {
            double TimeSinceLastEvent;
            double TimeSinceLastFrame;
        };

        FrameListener() {}
        ~FrameListener() {}

        virtual void FrameStart(FrameEvent& evt) = 0;
        virtual void FrameEnd(FrameEvent& evt) = 0;
        virtual void OnFrame(FrameEvent& evt) = 0;
    };

    class FrameListener_PyWrapper : public FrameListener, public boost::python::wrapper<FrameListener>
    {
    public:
        FrameListener_PyWrapper() {}    
        ~FrameListener_PyWrapper();

        void FrameStart(FrameEvent& evt);
        void FrameEnd(FrameEvent& evt);
        void OnFrame(FrameEvent& evt);
    };

然后对类进行包装以增强python的性能:

^{pr2}$

这可以在python中重写以创建自己的帧侦听器类:

class SimpleListen(FrameListener):
def __init__(self):
    pass
def FrameEndd(self, evt):
    pass

然后创建新SimpleListener类的实例,并使用核心将其“注册”到引擎_ENGINE.AddFrameListener()功能。然后,该函数使用boost::python::extract()来提取它,并将其放在std::vector of frame侦听器上,然后每个帧执行该侦听器。这很好地工作,但是如果我忘记在简单类中定义base或者拼错了它,显然会导致崩溃。我在google上搜索过boost::python或C/pythonapi,如何测试基类是否定义正确。AddFrameListener接受PyObject*参数。我想首先测试PyObject是否是类类型。如果您不小心尝试输入一个整数值或一个字符串,程序将识别错误并显示该对象不是类类型的消息。如果它是类类型,我想测试它是否有基类,以及是否可以提取到FrameListener_PyWrapper*。稍后,我想测试每个单独的函数(FrameStart、FrameEnd和OnFrame)是否在python类中被重写,参数是否匹配。如何从python函数获取参数列表?如果python类中的任何函数没有被重写,它将给我一个警告。如果参数不匹配,并且您尝试调用:

if (boost::python::override f = this->get_override("FrameEnd"))
    {
        f(evt);
        return;
    }

它将导致没有任何错误信息的崩溃。我想在调用AddFrameListener函数时检查参数是否匹配,如果没有正确重写任何函数,引擎将不会调用它们。在


Tags: 函数参数virtualpublicclassevtboost侦听器
1条回答
网友
1楼 · 发布于 2024-06-07 04:31:45

崩溃可能与你调用Python而没有GIL锁定有关。每次与Python对象交互时都应该锁定它:

    /*
This RAII structure ensures that threads created on the native C side
adhere to the laws of Python and ensure they grab the GIL lock when
calling into python
*/
struct PyLockGIL
{

    PyLockGIL()
        : gstate(PyGILState_Ensure())
    { 
    }

    ~PyLockGIL()
    {
        PyGILState_Release(gstate);
    }

    PyLockGIL(const PyLockGIL&) = delete;
    PyLockGIL& operator=(const PyLockGIL&) = delete;

    PyGILState_STATE gstate;
};

然后在回调到Python之前使用它:

^{pr2}$

相关问题 更多 >