递归期间未调用Pybind11虚拟子类方法,而是调用了Base

时间:2018-10-04 13:50:40

标签: pybind11

我有一个简单的多态测试用例,它不能正常工作。.我有两个C ++类,Client和Dispatcher。调度程序具有一个称为“ Dispatch”的方法,该方法将Client *作为输入并调用客户机的虚拟ProcessEvent()方法。我已经使用下面的代码将这两个类都提供给了python。我从Client类派生为python类SomeClient,并重写了其ProcessEvent函数。当我从SomeClient :: ProcessEvent方法内的任何地方调用“ Dispatch”时,一切都按预期进行,因此我从子类中获得了报告。但是,当我从SomeClient :: ProcessEvent中调用Dispatch时,将调用基类ProcessEvent。有什么想法可能会出问题吗?我希望得到一个无限递归,导致SomeClient :: ProcessEvent被永远调用。

C ++:

#include <iostream>
#include "pybind11/pybind11.h"

namespace py = pybind11;
class Dispatcher;
class Client
{
public:
    Client(Dispatcher* disp): PtrD(disp)
    {
        std::cout << "In Client::Client\n";
    }
    virtual ~Client(){};
    virtual void ProcessEvent()
    {
        std::cout << "THIS SHOULDN'T HAPPEN --In Client::ProcessEvent\n";
    }
    Dispatcher* PtrD;
};

class Dispatcher
{
public:
    Dispatcher()
    {
        std::cout << "In Dispatcher::Dispatcher\n";
    }
    virtual ~Dispatcher(){};

    void Dispatch(Client* client)
    {
        std::cout << "Dispatcher::Dispatch called by " << client << std::endl;
        client->ProcessEvent();
    }
};

class DispatcherTrampoline : public Dispatcher
{
public:
    using Dispatcher::Dispatcher;
};

class ClientTrampoline : public Client
{
public:
    using Client::Client;

    void ProcessEvent() override
    {
        PYBIND11_OVERLOAD(void,Client,ProcessEvent,);
    }
};

PYBIND11_MODULE(libTestCase,mod)
{
    py::class_<Client,ClientTrampoline> cli(mod,"Client");
    cli.def(py::init<Dispatcher* >());
    cli.def("ProcessEvent",&Client::ProcessEvent);
    cli.def_readwrite("PtrD",&Client::PtrD);

    py::class_<Dispatcher,DispatcherTrampoline> dsp(mod,"Dispatcher");
    dsp.def(py::init< >());
    dsp.def("Dispatch",&Dispatcher::Dispatch);
}

Python测试:

from build.libTestCase import Client,Dispatcher

class SomeClient(Client):
    def __init__(self,d):
        print("In SomeClient::__init__")
        super().__init__(d);

    def ProcessEvent(self):
        print("in SomeClient::ProcessEvent,about to call self.ProcessEvent")
        self.PtrD.Dispatch(self);

if __name__ == "__main__":
    dd = Dispatcher()
    cl = SomeClient(dd)
    dd.Dispatch(cl)

终端输出:

In Dispatcher::Dispatcher
In SomeClient::__init__
In Client::Client
Dispatcher::Dispatch called by 0x20bb270
in SomeClient::ProcessEvent,about to call self.ProcessEvent
Dispatcher::Dispatch called by 0x20bb270
THIS SHOULDN'T HAPPEN --In Client::ProcessEvent

0 个答案:

没有答案