python - 如何在 C 回调中使用 Pybind11 访问 Python 对象?
问题描述
我有一个 C++ DLL,它使用Pybin11
. 项目的 Python 端接受回调并将一些参数传递给它们。然后在 C++/C/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>
所以我的问题是,我应该怎么做,这样我就不会在 Python 部分遇到异常?如何在 Python 中访问对象指针?有可能吗?
解决方案
这似乎是一个Pybind11
错误,在 Pybind11 上创建问题并没有帮助,所以我最终使用了委托回调。那就是使用中间回调在两种格式之间进行转换。我在之前的(相关)问题中详细解释了这一点。
推荐阅读
- swiftui - 如果父视图中已有工作表,则不能在 SwiftUI 的子视图中显示工作表
- java - 为什么 Criteria API 会抛出 StackOverFlow 异常?
- google-sheets - 通过比较一些值从其他电子表格中获取数据
- atl - 关于 ATL 140 ,这是 DECLARE_REGISTRY 中的错字吗?
- android - 自定义 FooterBarLayout 中没有滚动以跟随 AppBarLayout
- cakephp - 更改路径搜索顺序
- amazon-web-services - 为什么 aws s3 传输加速不起作用?
- android - 如何为我的 Android 应用程序创建一个圆形图标?
- c# - 如何循环 C# ARGGIS 异步方法(查看帖子以获取方法代码)
- math - 在 3D 中垂直于起始边缘捕捉拖动的鼠标位置