导出32位枚举时Boost Python 1.48失败 < PosithPython的新版本是否支持从C++输出完整的32位枚举?我使用的是1.48,最多可以导出30位,但每次尝试导出32位数字时,由于“访问冲突读取位置0x00000001”,它都会失败。深入研究enum.cpp文件,似乎在创建对象x时,它会将字节20设置为1,这会导致以后在p->name存在之前尝试递减时失败。我是否只需要升级到更新版本的boostpython,还是无法导出完整的32位数字?谢谢你的意见
编辑:由跳跳虎在工作时发现,在此为后代记录: 问题在于枚举对象结构的定义中。基本\u对象中的基础数字存储允许15位数字(短)或30位数字(整数)粒度,但基本\u对象仅包含足够的空间,用于2x 15位数字或1x 30位数字。存储>30位枚举值时,编码需要3个短字符或2个整数,具体取决于编译的格式。结果是name成员占用了额外数字存储所需的空间。引用减量失败,因为该值放置在名称成员期望的位置 解决方案是在name成员之前添加至少32位的填充,以处理32位枚举值。如果在不久的将来需要64位枚举,则应添加2个填充字导出32位枚举时Boost Python 1.48失败 < PosithPython的新版本是否支持从C++输出完整的32位枚举?我使用的是1.48,最多可以导出30位,但每次尝试导出32位数字时,由于“访问冲突读取位置0x00000001”,它都会失败。深入研究enum.cpp文件,似乎在创建对象x时,它会将字节20设置为1,这会导致以后在p->name存在之前尝试递减时失败。我是否只需要升级到更新版本的boostpython,还是无法导出完整的32位数字?谢谢你的意见,python,c++,boost,enums,Python,C++,Boost,Enums,编辑:由跳跳虎在工作时发现,在此为后代记录: 问题在于枚举对象结构的定义中。基本\u对象中的基础数字存储允许15位数字(短)或30位数字(整数)粒度,但基本\u对象仅包含足够的空间,用于2x 15位数字或1x 30位数字。存储>30位枚举值时,编码需要3个短字符或2个整数,具体取决于编译的格式。结果是name成员占用了额外数字存储所需的空间。引用减量失败,因为该值放置在名称成员期望的位置 解决方案是在name成员之前添加至少32位的填充,以处理32位枚举值。如果在不久的将来需要64位枚举,则应添
struct enum_object
{
#if PY_VERSION_HEX >= 0x03000000
PyLongObject base_object;
#else
PyIntObject base_object;
#endif
// ADD PADDING HERE TO FIX ALIGNMENT ISSUE
PyObject* name;
};
结束编辑
TL/DR:根错误要么在转换中,要么在通过enum_base::add_value函数的堆栈变量进行的假定对象对齐中,但可能最容易通过转换器查看值是否以某种方式损坏。我将尝试的另一个实验是交换.value调用的顺序(这可能有助于确定是否存在与堆栈相关的问题)
详细信息:enum_base::add_value函数在1.48和1.58(最新版本)之间保持不变。此外,基于python::api::object类和object_base_初始值设定项模板的显式转换“(*this)(value)”似乎也没有改变。我没有进一步遍历object_base构造函数以查看是否有任何更改;我建议使用不符合要求的值逐步执行转换序列,以查看上面两位是否出现任何异常(我不确定您是否会在那里找到任何东西,但值得检查)
请记住,转换后的值将被复制到堆栈“object x=(this)(value);”中,并且enum_object p的向下转换覆盖的对象大于在x.ptr()处引用的对象(即m_ptr成员)。此时我不确定m_ptr是堆栈还是堆(没有遍历这些细节),但无论哪种方式,如果p现在覆盖的是陈旧的或未初始化的内存,那么p->name处的引用减量将失败,如果它没有指向有效内存(如您所发现的)
我不确定是否需要p->name引用减量(对象生存期是本地的)。。。我得再考虑一下。我们可以在周一讨论更多。。。这是一个周末。。。休息一下(就像我应该说话一样!)
void enum_base::add_value(char const*name_u,long value)
{
//将名称转换为Python字符串
对象名称(名称);
//通过使用值调用类来创建新的枚举实例
对象x=(*此)(值);
//将对象存储在枚举类中
(*此).attr(name_uux)=x;
dict d=提取(此->属性(“值”)();
d[值]=x;
//在新枚举实例中设置名称字段
enum_object*p=downcast(x.ptr());
Py_XDECREF(p->name);
p->name=incremf(name.ptr());
dict names_dict=extract(这个->属性(“名称”)();
名称_dict[x.attr(“名称”)]=x;
}
void enum_base::add_value(char const* name_, long value)
{
// Convert name to Python string
object name(name_);
// Create a new enum instance by calling the class with a value
object x = (*this)(value);
// Store the object in the enum class
(*this).attr(name_) = x;
dict d = extract<dict>(this->attr("values"))();
d[value] = x;
// Set the name field in the new enum instanec
enum_object* p = downcast<enum_object>(x.ptr());
Py_XDECREF(p->name);
p->name = incref(name.ptr());
dict names_dict = extract<dict>(this->attr("names"))();
names_dict[x.attr("name")] = x;
}