我想最近描述一下我所面临的情况,以便为这个问题提供一些背景。
我正在编写一个 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++限制是什么?
这是错误的方法,因为你永远无法构造你的对象!相反,您可以做的是在PyObject
和对象之间定义一个映射:
std::unordered_map<PyObject*, CxxStff> stuff;
void foo(PyObject* o) {
CxxStuff& extra = stuff[o];
// etc
}
把你想要的任何东西放在额外的课程中,你就会很高兴。
一个格式不正确的问题。事后诸葛亮20:20,事情是这样的:
我正在处理一个使用 C 样式继承方案的 C 库,即
struct CBase{
int a,b;
}
struct CDer{
CBase ab;
int c;
}
我正在计划我的C++代码:
class CxxBase : CBase
因此,如果我从 C 获得指针,我可以类型转换为等效的 CxxBase 对象,反之亦然。
问题是C++管理继承的方式与 C 示例几乎相同。 Final:Der:Base 将在连续内存中存储一个 Base,然后存储一个 Der,然后存储一个 Final 对象。
所以不可能执行这种结合。CDer和CxxDer的大小都是未知的。
需要一种不同的技术,例如巴里提出的映射。
但是,这涉及相当昂贵的查找。
在我正在从事的项目中,我看不到比现有解决方案更好的解决方案:
struct Bridge {
CObj cob;
CxxObj* p_cxxob;
}
const CxxObj& to_cxx(CObj* cob) { return *(cob->p_cxxob); }