Как связать этот класс и функцию C++ с pybind11?

Я пытаюсь связать библиотеку 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'>
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
#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

Спасибо @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);

crossmax 02.09.2024 21:21

@crossmax, должно быть, запрашивает правильное преобразование типов с помощью static_cast, я обновил свой скрипт, проверьте его.

Rohit Rajput 03.09.2024 05:24

с вашим обновлением и добавлением «std::unique_ptr<CT_API, py::nodelete>» в определение класса компиляция модуля работает. Но у меня возникает ошибка при вызове функции экземпляра FOO_API из файла main.py. Ошибка связана с несовместимыми аргументами функции. Я обновил свой ответ, чтобы включить его

crossmax 03.09.2024 12:48

@crossmax Я отредактировал свой ответ, включив в него код Python для его проверки. Надеюсь, это будет окончательный вариант. Если проблема все еще остается, создайте новый вопрос с данной ошибкой.

Rohit Rajput 04.09.2024 12:18

спасибо за помощь. С вашим кодом и добавлением «unique_ptr...» при определении класса FOO_API работает

crossmax 05.09.2024 09:46

Другие вопросы по теме