重命名 SWIGTYPE 并将代码注入生成的类
Renaming a SWIGTYPE and injecting code to the generated class
我正在扩展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()
,所以这仍然有待完成,但是上面应该回答我在原始问题中的所有担忧。
- 如何使用可视化代码和平台IO将环境变量注入CPP文件?
- 在注入的 Dll 的 DllMain 中运行代码导致注入超时
- 通过 dll 注入在主线程中执行代码
- LLVM Clang C 代码注入
- 类型擦除代码的依赖注入单元测试
- C - 将代码注入运行过程(使用DLL)
- 该代码注入第三方Qt应用程序并执行一些方法来获取Qt应用程序信息
- 此代码是否容易受到 SQL 注入的攻击?我该如何使其安全
- 重命名 SWIGTYPE 并将代码注入生成的类
- 注入我的代码后游戏滞后
- 嵌入式系统上的C++动态代码注入
- 引脚类似工具,用于编译时注入检测代码
- Dll 注入 - 在另一个进程中编写本机代码
- 将x86代码注入x64进程
- 如何在C++中打印堆栈跟踪,并在C++中注入代码
- 是否有可能制作一个函数包装器来运行注入的代码并返回与注入的函数相同的数据
- 使用代码洞穴注入64位DLL
- C++代码注入使注入的应用程序崩溃
- 我应该使用依赖注入或不为了有一个良好的设计和可测试的代码
- C++注入代码