В настоящее время у меня есть эта подпись в моем классе С++:
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:
при использовании 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 чтобы получить базовый указатель на буфер, а затем использовать его.
Поскольку это void *, у меня также не возникнет проблем с его использованием в качестве сигнатуры функции C, так что все должно быть в порядке!
но я думаю, это предположение здесь не выполняется или я что-то упускаю.
Что я здесь упускаю и каковы мои варианты раскрытия pybin11::objects, такие как pybind11::array_t в C
?