Я пытаюсь связать библиотеку C++ с pybind11. У меня есть класс, который генерирует экземпляр для вызова основных функций, которые я не знаю, как связать.
/*!
* @/class FOO_API
* @/brief Structure for API support
*/
class FOO_API {
public:
/*!
* @fn Instance
* @brief Class instance constructor FOO_API
* @return FOO_API* Return an initialized FOO_API object
*/
static FOO_API* instance(struct config1 conf1, struct config2 conf2);
/*!
* @fn Liberate
* @brief Free memory
*/
static void liberate();
private:
/*!
* @fn FOO_API()
* @brief Create an empty object FOO_API
*/
FOO_API();
/*!
* @fn FOO_API(const FOO_API& orig)
* @brief Create object from another
* @param orig { Param FOO_API }
*/
FOO_API(const FOO_API& orig);
/*!
* @fn virtual ~FOO_API()
* @brief Free memory
*/
virtual ~FOO_API();
static FOO_API* m_pInstance;
static class FOO_API_Impl* m_pInstanceImpl;
};
В файле-обертке я положил что-то вроде этого:
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "FOO_API.h"
namespace py = pybind11;
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin";
py::class_<config1>(m, "config1")
.def(py::init<>())
.def_readwrite("foo", &config1::foo)
py::class_<config2>(m, "config2")
.def(py::init<>())
.def_readwrite("bar", &config2::bar)
py::class_<FOO_API>(m, "FOO_API")
.def(py::init<>())
m.def("instance", &instance);
Когда я пытаюсь скомпилировать обертку, я получаю эту ошибку:
error: ‘instance’ was not declared in this scope
m.def("instance", &instance);
Как мне создать класс FOO_API и как мне вызвать функцию экземпляра() из кода оболочки C++? Спасибо за ваши комментарии
ОБНОВЛЕНИЕ 1:
Изменение класса FOO_API по рекомендации Рахута.
// Exposing FOO_API class and its static methods
py::class_<FOO_API, std::unique_ptr<FOO_API, py::nodelete>>(m, "FOO_API")
// Use py::init to expose the constructor, but the constructor is private
// so we are not exposing it directly.
.def_static("instance",
static_cast<FOO_API* (*)(config1, config2)>(&FOO_API::instance),
py::return_value_policy::reference)
.def_static("liberate", &FOO_API::liberate);
И вызов функции привязки из кода Python следующим образом:
import example as wrapper
conf1 = wrapper.config1
conf2 = wrapper.config2
pointerFOO_API = wrapper.FOO_API.instance(conf1, conf2)
вернул эту ошибку
Traceback (most recent call last):
File "main.py", line 160, in <module>
pointerFOO_API = wrapper.FOO_API.instance(conf1, conf2)
TypeError: instance(): incompatible function arguments. The following argument types are supported:
1. (arg0: example.config1, arg1: example.config2) -> example.FOO_API
Invoked with: <class 'example.config1'>, <class 'example.config2'>





#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "FOO_API.h"
namespace py = pybind11;
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin";
py::class_<config1>(m, "config1")
.def(py::init<>())
.def_readwrite("foo", &config1::foo);
py::class_<config2>(m, "config2")
.def(py::init<>())
.def_readwrite("bar", &config2::bar);
// Exposing FOO_API class and its static methods
py::class_<FOO_API>(m, "FOO_API")
// Use py::init to expose the constructor, but the constructor is private
// so we are not exposing it directly.
.def_static("instance",
static_cast<FOO_API* (*)(config1, config2)>(&FOO_API::instance),
py::arg("conf1"), py::arg("conf2"),
py::return_value_policy::reference)
.def_static("liberate", &FOO_API::liberate);
}
main.py чтобы проверить это:
import example as wrapper
# Create instances of config1 and config2
conf1 = wrapper.config1() # Instantiate config1
conf2 = wrapper.config2() # Instantiate config2
# Pass the instances to the FOO_API.instance() method
pointerFOO_API = wrapper.FOO_API.instance(conf1, conf2)
# Now you can use pointerFOO_API
@crossmax, должно быть, запрашивает правильное преобразование типов с помощью static_cast, я обновил свой скрипт, проверьте его.
с вашим обновлением и добавлением «std::unique_ptr<CT_API, py::nodelete>» в определение класса компиляция модуля работает. Но у меня возникает ошибка при вызове функции экземпляра FOO_API из файла main.py. Ошибка связана с несовместимыми аргументами функции. Я обновил свой ответ, чтобы включить его
@crossmax Я отредактировал свой ответ, включив в него код Python для его проверки. Надеюсь, это будет окончательный вариант. Если проблема все еще остается, создайте новый вопрос с данной ошибкой.
спасибо за помощь. С вашим кодом и добавлением «unique_ptr...» при определении класса FOO_API работает
Спасибо @rohit-rajput, но что-то не работает. example.cpp:137:153: ошибка: нет соответствующей функции для вызова 'pybind11::class_<FOO_API>::def_static(const char [9], <неразрешенный тип перегруженной функции>, pybind11::arg, pybind11::arg , pybind11::return_value_policy)' ic("instance", &FOO_API::instance, py::arg("conf1"), py::arg("conf2"), py::return_value_policy::reference);