Open singhanubhav2000 opened 5 years ago
is this different that #1508? Code doesn't compile, need a more complete example.
The code is similar but this is a different discussion. All I wanted was how to manage reference count for the scenario I mentioned above.
If you pass around pybind11::object
objects, then the reference counting is handled for you.
If you use the python c api, like raw PyObject
, or pybind11::handle
, then you need to handle reference counting for those objects manually.
I have a problem where the code is panicing when I am making python call from C++. Its on the line of the above discussion: the python snippet is import utils import TplatPythonInterface
class TplatPyModule: def init(self): pass
def connect(self, tplatEndpointInfo):
self.cls = utils.getClassByName(tplatEndpointInfo.plugin_path,
tplatEndpointInfo.sub_plugin,
tplatEndpointInfo.application)
self.cls.connect(tplatEndpointInfo.endpoint_ip, tplatEndpointInfo.blob)
Here is binding code
namespace py = pybind11;
Here epInfo_(of type tplatEndpointInfo*) is defined in the base class smaTplatInterface,
class attribute((visibility("hidden"))) tplatPyWrapper : public smaTplatInterface { static pybind11::module module; pybind11::object pyModule; <-- Pointer to python class static pybind11::object import(const std::string& module, const std::string& path, pybind11::object& globals); public: static void initialize(); static void finalize(); tplatPyWrapper(tplatEndpointInfo* epInfo); ~tplatPyWrapper() {}
SmaStatus connect();
};
py::module tplatPyWrapper::module_;
PYBIND11_MAKE_OPAQUE(tplatEndpointInfo);
PYBIND11_EMBEDDEDMODULE(TplatPythonInterface, m) { m.doc() = "Thirdplatform framework to python binding"; py::class(m, "TplatEndpointInfo", py::call_guard()) .def(py::init<>(), py::return_value_policy::reference_internal) .defreadwrite("application", &tplatEndpointInfo::application, py::return_value_policy::reference_internal) .def_readwrite("endpoint_path", &tplatEndpointInfo::endpointpath, py::return_value_policy::reference_internal) .def_readwrite("endpoint_ip", &tplatEndpointInfo::endpointip, py::return_value_policy::reference_internal) .def_readwrite("sub_plugin", &tplatEndpointInfo::subplugin, py::return_value_policy::reference_internal) .def_readwrite("plugin_path", &tplatEndpointInfo::pluginpath, py::return_value_policy::reference_internal) .defreadwrite("blob", &tplatEndpointInfo::blob, py::return_value_policy::reference_internal)
The code is panicing at the time when we are trying to call the connect function as defined under.
static void tplatPyWrapper::initialize() { py::initializeinterpreter(); py::object main = py::module::import("main"); py::object globals = main.attr("dict"); module = py::module::import("tplatPyModule"); }
tplatPyWrapper::tplatPyWrapper() { auto tplatPyModuleClass = module.attr("TplatPyModule"); pyModule = tplatPyModuleClass(); }
SmaStatus tplatPyWrapper::connect() { auto connect = pyModule.attr("connect"); connect(epInfo); return SMAOK; } initialize(); tplatPyWrapper* tp = new tplatPyWrapper(epInfo); tp->connect();
(gdb) bt
Hi Guys, Any idea how to fix the issue? Any help would be greatly appreciated.
I have a use-case where I have implemented an API in python and that needs to be invoked by C++.
struct ABC { ABC(int _i, int _j) { i = _i; j = _j; } int i; int j; };
struct listABC { listABC() {} std::string name; std::vector lst ;
};
PYBIND11_MAKE_OPAQUE(std::vector);
PYBIND11_MODULE(cc11binds, m) {
py::class(m, "ABC")
.def(py::init<double, double>())
;
py::class_(m, "listABC")
.defreadwrite("name", &listABC::name)
.defreadwrite("lst", &listABC::lst)
;
py::bind_vector<std::vector>(m, "ABCTest", py::module_local(false));
}
struct listABC { std::string name; std::vector lst ; };
cumabc(&abcList) -> this takes reference to vector object. This works fine:
before cumabc, in C++ --- 2 [i:1 :: j:2] after cumabc, in C++ --- 2 [i:1 :: j:2, i:3 :: j:4] Where (3,4) is added by python interpreter.
cumlistABC(&listAbcWrapper) -> This takes reference to listABC object.