将基础设置为未确定大小的对象

时间:2014-12-25 21:22:08

标签: python c++ c++11 memory-management base-class

我想最近描述一下我面临的情况,以便提出一些问题。

我正在编写Python C ++包装器。 Python的基本单元是PyObject。 Python中的每个实体都是PyObject +更多可选的东西

也就是说保证第一个sizeofPyObject)字节填写PyObject的字段,但各种对象可能会分配额外的连续内存。

这样做的好处(原因?)是任何东西都可以被强制转换回有意义的PyObject

我试图包裹这样一只野兽:

class CxxWrapper : PyObject {}

假设我创建了一个void foo(PyObject* p),并将foo插入到一个Python运行时的函数指针表中。

然后运行时将触发此函数(无论出于何种原因)将指针传递给相关的PyObject

我希望能够将这种直接类型转换回相应的CxxWrapper对象:

CxxWrapper* cxxw = static_cast<CxxWrapper>p;

但是,我无法通过任何方式让这种机制发挥作用。因为我无法找到将基础对象设置为PyObjectPlusExtra的任何方法。

有没有办法做到这一点?如果没有,那么C ++的限制是什么?

2 个答案:

答案 0 :(得分:1)

这是错误的做法,因为你永远无法构建你的对象!你可以做的是在PyObject和你的对象之间定义一个地图:

std::unordered_map<PyObject*, CxxStff> stuff;

void foo(PyObject* o) {
    CxxStuff& extra = stuff[o];
    // etc
} 

把你想要的东西放在那个额外的课堂上,你会很高兴。

答案 1 :(得分:0)

一个形成错误的问题。事后20:20,这是正在发生的事情:

我正在处理C库使用C风格的继承方案,即

struct CBase{
    int a,b;
}

struct CDer{
    CBase ab;
    int c;
}

我正在计划我的C ++代码:

class CxxBase : CBase

因此,如果我从C获得指针,我可以将类型转换为等效的CxxBase对象,反之亦然。

问题是C ++管理的继承与C示例几乎相同。最后:Der:Base将存储一个Base然后是Der,然后是一个Final对象在连续的内存中。

所以不可能完成这个联盟。 CDer和CxxDer的大小都是未知的。

需要一种不同的技术,例如Barry提出的映射。

然而,这涉及相当昂贵的查询。

我看不到比我正在进行的项目中的现有解决方案更好的解决方案:

struct Bridge {
    CObj cob;
    CxxObj* p_cxxob;
}

const CxxObj& to_cxx(CObj* cob) { return *(cob->p_cxxob); }