Как выставить объект pybind11 :: в C? - PullRequest
1 голос
/ 09 апреля 2020

В настоящее время у меня есть эта подпись на моем классе C ++:

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

, и в моем коде клиента у меня просто есть:

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());

    cv::imshow("from callback", img1);
    auto timenow = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
    std::cout << "\narg1: " << status << " arg2: " << id << " arg3: " << typeid(img).name() << " " << ctime(&timenow) << std::endl;
}

, и это прекрасно работает для C++. но теперь я решил сделать из этого DLL-библиотеку и, таким образом, раскрыть функциональные возможности этого класса в C. Вот где я застрял!
Я пытался использовать:

typedef void(*CCallbackFn)(bool, char*, unsigned char);
typedef void(*CCallbackFn)(bool, char*, void*);

, но они не работают, так как я получаю исключение для Python part:
при использовании unsigned char:

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

Invoked with: True, '5', array([[[193, 218, 237],
        [193, 218, 237],
        [192, 217, 235],
        ...,

       [[193, 218, 237],
        [193, 218, 237],
        [192, 217, 235],
        ...,
        [ 68,  51,  88],
        [ 69,  54,  88],
        [ 72,  58,  92]]], dtype=uint8)

и при использовании void * я получаю:

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],
        [195, 216, 239],
        [193, 214, 236],
        ...,

       [[131, 147, 153],
        [124, 140, 146],
        [116, 126, 136],
        ...,
        [100, 108, 144],
        [104, 112, 148],
        [104, 112, 148]]], dtype=uint8)

Я предположил, так как имею дело с OpenCV изображением, и это объект (более того, он должен быть передается как PyObject мне, верно?), void * может быть жизнеспособным вариантом, а в части C++ я могу преобразовать это в PyObject, чтобы получить базовый указатель на буфер и затем использовать его.
Так как это пустота *, у меня также не возникло бы проблем с использованием его в качестве сигнатуры функции C, поэтому все должно быть хорошо!
но я думаю, что это предположение не выполняется или я что-то упустил.
Чего мне здесь не хватает и какие у меня есть варианты в представлении pybin11 :: объектов, таких как pybind11 :: array_t в C?

1 Ответ

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

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

...