C++ 返回标准::无序的地图<;标准::字符串,int>;密钥为pybind11::字节
考虑以下Pybind11代码:C++ 返回标准::无序的地图<;标准::字符串,int>;密钥为pybind11::字节,c++,pybind11,C++,Pybind11,考虑以下Pybind11代码: #include <string> #include <unordered_map> #include <pybind11/stl.h> #include <pybind11/pybind11.h> struct foo { foo() { data.emplace("\xde\xad\xbe\xaf", 1); } std::unordered_map
#include <string>
#include <unordered_map>
#include <pybind11/stl.h>
#include <pybind11/pybind11.h>
struct foo {
foo() {
data.emplace("\xde\xad\xbe\xaf", 1);
}
std::unordered_map<std::string, int> data;
};
PYBIND11_MODULE(example, m) {
pybind11::class_<foo>(m, "foo")
.def(pybind11::init())
.def_readonly("data", &foo::data);
}
#包括
#包括
#包括
#包括
结构foo{
foo(){
数据放置(“\xde\xad\xbe\xaf”,1);
}
std::无序的地图数据;
};
PYBIND11_模块(示例,m){
pybind11::类(m,“foo”)
.def(pybind11::init())
.def_只读(“数据”、&foo::数据);
}
当调用python2example.foo().data
时,它抛出UnicodeDecodeError
——因为数据
键不包含有效的UTF。查看pybind11/cast.h,我们可以看到string\u caster::cast()
总是尝试解码\u utfN()
,这就是导致上述异常的原因
如何说服Pybind11将键视为
字节
?如何将值复制到dict
,并将字节
作为键?这样行吗
struct foo {
foo() {
data.emplace("\xde\xad\xbe\xaf", 1);
}
std::unordered_map<std::string, int> data;
};
PYBIND11_MODULE(example, m) {
pybind11::class_<foo>(m, "foo")
.def(pybind11::init())
.def_property_readonly("data", [](const foo& f)
{
pybind11::dict d;
for(const auto& v : f.data )
{
d[pybind11::bytes(v.first)] = v.second;
}
return d;
});
}
好吧,这将创建一个新对象。问题是是否可以包装原始版本。我不是pybind11专家,但我检查了标题,在您的情况下,如果您转换为
std::string
aPyUnicode\u DecodeUTF8
CPython
函数将被调用。这也会创建一个新对象。我从未创建过代理,但我在pybind11/numpy.h
头文件中见过它们。例如,pybind11/stl.h
中的array\u caster
创建新列表并向其添加新对象。所以我认为“铸造”创造了新的物体。如果我错了,请随时纠正我。
>>> import example
>>> example.foo().data
{b'\xde\xad\xbe\xaf': 1}
>>>