Как можно получить доступ к объекту Python с помощью Pybind11 в обратном вызове C? - PullRequest
2 голосов
/ 11 апреля 2020

У меня есть C ++ DLL, которая встраивает интерпретатор python, используя Pybin11. Сторона Python проекта принимает обратные вызовы и передает им некоторые аргументы. Затем обратные вызовы выполняются в части C ++ / C / C# et c. На стороне C ++ я могу свободно использовать pybind11::object, могу обрабатывать сложные типы, такие как изображения OpenCV (например, py::array_t); однако, когда дело доходит до предоставления C, который затем может использоваться для различных языков, включая C#, я терплю неудачу.

Причина, по которой я терплю неудачу, заключается в том, что я не могу просто разыграть py::object к типу, который C понимает, и наоборот. например, я не могу просто изменить свой обратный вызов C ++:

typedef void(*CallbackFn)(bool, std::string, py::array_t<uint8_t>&);

void default_callback(bool status, std::string id, py::array_t<uint8_t>& img)
{
    auto rows = img.shape(0);
    auto cols = img.shape(1);
    auto type = CV_8UC3;
    cv::Mat img1(rows, cols, type, img.mutable_data());
   ...

}

на его C совместимый вариант:

typedef void(*CallbackFn)(bool, char*, void*);
void default_callback(bool status, char* id, void* img)
{
    //cast the void* into something useful
    ...
}

Это просто вызывает исключение для Python сторона, которая просто говорит:

TypeError: (): incompatible function arguments. The following argument types are supported:
    1. (arg0: bool, arg1: str, arg2: capsule) -> None

Invoked with: True, '5', array([[[195, 216, 239],
        [194, 215, 237],
        [193, 214, 236],
        ...,
        [ 98, 108, 143],
        [100, 110, 147],
        [101, 111, 149]]], dtype=uint8)

, используя другие объекты (например, на opencv img.data Я получаю такие ошибки, как:

TypeError: (): incompatible function arguments. The following argument types are supported:
    1. (arg0: bool, arg1: str, arg2: capsule) -> None

Invoked with: True, '5', <memory at 0x0000021BC3433D68>

Итак, мой вопрос, как я должен go об этом, чтобы я не получил исключение для Python части? Как я могу получить доступ к указателю объекта в Python? Это вообще возможно?

1 Ответ

1 голос
/ 18 апреля 2020

Это похоже на ошибку Pybind11, и создание проблемы в Pybind11 не помогло, поэтому я в итоге использовал обратный вызов делегата. То есть используйте средний обратный вызов для преобразования между двумя форматами. Я объяснил это подробно в моем предыдущем (связанном) вопросе .

...