Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
导出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 - Fatal编程技术网

导出32位枚举时Boost Python 1.48失败 < PosithPython的新版本是否支持从C++输出完整的32位枚举?我使用的是1.48,最多可以导出30位,但每次尝试导出32位数字时,由于“访问冲突读取位置0x00000001”,它都会失败。深入研究enum.cpp文件,似乎在创建对象x时,它会将字节20设置为1,这会导致以后在p->name存在之前尝试递减时失败。我是否只需要升级到更新版本的boostpython,还是无法导出完整的32位数字?谢谢你的意见

导出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位枚举,则应添

编辑:由跳跳虎在工作时发现,在此为后代记录:

问题在于枚举对象结构的定义中。基本\u对象中的基础数字存储允许15位数字(短)或30位数字(整数)粒度,但基本\u对象仅包含足够的空间,用于2x 15位数字或1x 30位数字。存储>30位枚举值时,编码需要3个短字符或2个整数,具体取决于编译的格式。结果是name成员占用了额外数字存储所需的空间。引用减量失败,因为该值放置在名称成员期望的位置

解决方案是在name成员之前添加至少32位的填充,以处理32位枚举值。如果在不久的将来需要64位枚举,则应添加2个填充字

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;
}