Reputation: 25924
I have a C++ DLL that embeds python interpreter using Pybin11
. The Python side of the project accepts callbacks and passes some arguments to them. The callbacks then are executed on the C++/C/C# etc part. On C++ side I can freely use pybind11::object
can handle complex types such as OpenCV images (using py::array_t
for example); however, when it comes to exposing it to the C which can be then used for variety of languages including C#, I fail.
The reason I fail, is that I can't simply cast the py::object
to a type that C understands and vice versa. for example, I can't simply change my C++ callback which is :
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());
...
}
to its C compatible variant :
typedef void(*CallbackFn)(bool, char*, void*);
void default_callback(bool status, char* id, void* img)
{
//cast the void* into something useful
...
}
This simply causes an exception on Python side which simply says,
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)
using other objects (for example on an opencv img.data
I get errors such as this :
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>
So my question is, how should I go about this, so that I don't get an exception on Python part? How can I access to an object pointer in Python? is it even possible?
Upvotes: 3
Views: 590
Reputation: 25924
This seems like a Pybind11
bug and creating an issue on Pybind11 didn't help, so I ended up using a delegate callback. That is use a middle callback for converting between the two format. I explained this in detail in my previous (related) question.
Upvotes: 1