重命名 SWIGTYPE 并将代码注入生成的类

Renaming a SWIGTYPE and injecting code to the generated class

本文关键字:注入 代码 SWIGTYPE 重命名      更新时间:2023-10-16

我正在扩展jCAE/occjava,用于使用SWIG生成的接口从Java访问OpenCasCade C++库。

一些C++侧对象需要比较相等性,即运算符==

特别是类Handle_Standard_Type的实例,这些实例像在库中一样用于使用单例表示动态类型信息,即或多或少类似于枚举。不要认为这无关紧要,只是把它作为背景信息放在这里。

我可以使用以下SWIG定义来执行此操作

%typemap(javacode) Handle_Standard_Type& %{
public boolean equals(Object obj) {
boolean equal = false;
if (obj instanceof $javaclassname)
equal = ((($javaclassname)obj).swigCPtr == this.swigCPtr);
return equal;
}
%}

但是,这会生成一个丑陋的类名SWIGTYPE_p_Handle_Standard_Type

我尝试了我能找到的所有方法,例如:

从生成的类名中删除 SWIGTYPE

但是,如果我按照建议进行操作并添加到我的 SWIG 定义中:

class Handle_Standard_Type {}

我确实摆脱了丑陋的名字,但equals()方法没有注入到 Java 类中。

更复杂的是,OCC 中的大多数类都是使用 处理因此,对于每个C++类Example都有一个Handle_Example类。 为了摆脱Java方面的丑陋,occjava项目SWIG定义有很多定义,例如:

%rename(Example) Handle_Example;

所以我需要我的解决方案遵循这个命名约定,因此最终生成的 Java 类需要命名为Standard_Type而不是Handle_Standard_Type

以下是一些更多详细信息,以防它们相关或可能影响所走的路径。

下面是 OCC 中的动态类型如何工作的示例,或者更准确地说,如何使用 SWIG 从 Java 访问它。

在SWIG中,我们有这样的定义:

%{
#include <Geom_Geometry.hxx>
#include <Geom_Plane.hxx>
%}
%rename(Geom_Geometry) Handle_Geom_Geometry;
%rename(Geom_Plane) Handle_Geom_Plane;
%extend Handle_Geom_Geometry {
const Handle_Standard_Type& DynamicType() 
{
return (*self)->DynamicType();
}   
}
class Handle_Geom_Plane: public Handle_Geom_Geometry
{
Handle_Geom_Plane()=0;
};
%extend Handle_Geom_Plane {
static const Handle_Standard_Type& STANDARD_TYPE() 
{
return STANDARD_TYPE(Geom_Plane);
}   
}

在上面的(*self)->DynamicType()STANDARD_TYPE(Geom_Plane)返回一个表示相关类类型的单例。那里使用了很多宏观魔法。

我之所以显示这些细节,是因为我不确定我的排版图定义旨在匹配Handle_Standard_Type&是否是正确的方法,并且我就如何最好地处理此问题提出了开放建议。

最重要的是,在C++端,我需要访问STANDARD_TYPE()宏和函数DynamicType返回的值,并在 Java 端将它们与equals()进行比较,以获得 C==的语义等效项。

喜欢这个

Geom_Surface aSurface = ....
if (aSurface.DynamicType().equals(Geom_Plane.STANDARD_TYPE())) {
....
}

在 "swig-user@lists.sourceforge.net" -list 的帮助下解决了这个问题。

问题是类定义需要放在 类型映射定义。

我错误地假设类 def 需要在类型映射之前 因为通常在编程语言中,您在使用类型之前会引入
类型,但当然在这里它的工作方式正好相反,因为它是 重要的类型映射的范围,如 SWIG 用户手册"10.2.2 类型映射范围"中所述:

"一旦定义,类型图对随后的所有声明仍然有效。

以下是对我有用的SWIG定义:

%rename(Standard_Type) Handle_Standard_Type;
%typemap(javacode) Handle_Standard_Type %{  
public boolean equals(Object obj) {
boolean equal = false;
if (obj instanceof $javaclassname)
equal = ((($javaclassname)obj).swigCPtr == this.swigCPtr);
return equal;
}
%} 
class Handle_Standard_Type {};

在Java中,还应该记住在覆盖equals()时覆盖hashCode(),所以这仍然有待完成,但是上面应该回答我在原始问题中的所有担忧。