将结构更改为类(和其他类型更改)和ABI /代码生成

Leu*_*nko 6 c++ swig abi

它已经成熟并且是一个规范的参考问题,在C++结构和类中,在手动编写代码时几乎可以互换.

但是,如果我想链接到现有代码,如果我在原始代码之后将头重新声明为一个类,或者反之亦然,我可以期望它能够产生任何差异(例如,中断,鼻子恶魔等)产生的?

所以这种情况是被编译成一个结构(或类)的类型,而我改变了头文件到其他声明,包括它在我的项目之前.

真实世界的用例是我用SWIG自动生成代码,根据是给定结构还是类,生成不同的输出; 我需要将其中一个更改为另一个以使其输出正确的界面.

这个例子在这里(Irrlicht,SVertexManipulator.h) - 给出:

struct IVertexManipulator
{
};
Run Code Online (Sandbox Code Playgroud)

我机械地重新声明它:

/*struct*/class IVertexManipulator
{public:
};
Run Code Online (Sandbox Code Playgroud)

原始库使用原始标题进行编译,不受影响.包装器代码使用修改后的表单生成,并使用它们进行编译.然后将这两个链接到同一个程序中以便一起工作.假设我对两个库使用完全相同的编译器.

这种事情是不确定的?"未定义",但预计会在现实编译器上工作?完全允许?

我正在做的其他类似的更改包括从参数中删除一些默认值(以防止歧义),以及从SWIG不可见类型的几个类中删除字段声明(这改变了类的结构,我的推理是生成的代码应该需要该信息,仅链接到成员函数).再次,这会造成多大的破坏?

例如IGPUProgrammingServices.h:

s32 addHighLevelShaderMaterial(
    const c8* vertexShaderProgram,
    const c8* vertexShaderEntryPointName/*="main"*/,
    E_VERTEX_SHADER_TYPE vsCompileTarget/*=EVST_VS_1_1*/,
    const c8* pixelShaderProgram=0,
...
Run Code Online (Sandbox Code Playgroud)

CIndexBuffer.h:

public:
    //IIndexList *Indices;
Run Code Online (Sandbox Code Playgroud)

......等等.其他更改包括使用typedef替换某些模板参数类型并packed从某些结构中删除该属性.同样,如果更改的结构声明从未在机器代码中实际使用(仅生成链接到主库中的访问器函数的名称),似乎应该没有问题,但这是否可靠?这样的情况?

asc*_*ler 2

这在技术上是未定义的行为。

3.2/5:

程序中可以有多个类类型的定义,[...或其他应该在头文件中定义的东西...],前提是每个定义出现在不同的翻译单元中,并且定义满足以下要求。给定这样一个名为D定义在多个翻译单元中的实体,则

  • 每个定义D应由相同的标记序列组成;和

  • ...

...如果 的定义D满足所有这些要求,那么程序的行为就好像有单一的 定义一样D。如果 的定义D不满足这些要求,则行为未定义。

本质上,您将第一个标记从 更改为structclass并根据需要插入标记public和。:标准不允许这样做。

但在我熟悉的所有编译器中,这在实践中都很好。


我所做的其他类似更改包括从参数中删除一些默认值(以防止歧义)

如果声明恰好不在类定义内,这实际上是正式允许的。不同的翻译单元甚至 TU 内的不同作用域可以定义不同的默认函数参数。所以你可能在那里也很好。

其他更改包括用其 typedef 替换一些模板参数类型

在类定义之外也正式允许:使用不同方式命名相同类型的函数的两个声明引用相同的函数。

...删除字段声明...并从某些结构中删除打包属性

不过,现在你正处于严重危险的境地。我不熟悉 SWIG,但如果你做这种事情,你最好确保使用这些“错误”定义的代码永远不会:

  • 创建或销毁类类型的对象

  • 定义一个继承或包含类类型成员的类型

  • 使用类的非静态数据成员

  • 调用使用类的非静态数据成员的内联函数或模板函数

  • 调用virtual类类型或派生类型的成员函数

  • 尝试查找sizeofalignof类类型