Swig 如何定义将 C 类型定义的布尔值转换为 java 布尔值的类型映射
Swig how to define a typemap that converts a C typedefined Boolean to java boolean
我正在使用 swig 在 C 和 Java (Android) 之间创建胶水。
我在 C 中定义了一个 Boolean 类型并像这样使用:
(MyGlue.h)
typedef enum boolean {
TRUE = 0x1,
FALSE = 0x0
} Boolean;
Boolean booleanValue = TRUE;
Boolean isRunning() {
return booleanValue;
}
然后在 Java 我想做以下事情:
if(MyGlue.isRunning) {
..do something..
}
我遇到的问题是 MyGlue.isRunning returns 一个 int
我可以制作一个将 int 转换为布尔值的 swig typemap 吗?
我试过以下方法,但我没有完全掌握swig typmap的用法:
在我的 swig 配置文件中添加了 follwing
%typemap(out) Boolean {
$result = boolean();
}
我没有得到我想要的东西,此外我不知道把从 int 到 boolean 的转换放在哪里,比如 (return_value != 0) 我想我需要在类型图。
是否可以用 swig 实现这种转换,所以在外部我处理布尔值而不是整数?
你在类型映射方面走在了正确的轨道上,事实上你可以使用 in/out 类型映射来做到这一点,但你还需要设置 jstype/jnitype/jtype 类型映射才能改变生成方法的签名。
一般而言,Java 类型映射存在从 C->JNI 中间体->最终 Java 类型的转换。如果您要自己编写类型映射,那么仅在 "Final Java types" 阶段执行此操作将是编写所需类型映射最少的代码的最简单位置。我整理了一个示例来向您展示那是什么样的。实际上,这意味着只更改 javain、javaout 和 jstype 类型映射:
%module test
%{
#include "test.h"
%}
%typemap(jstype) enum boolean "boolean"
%typemap(javacode) enum boolean %{
public boolean toBoolean() {
return this == TRUE;
}
%}
%typemap(javaout) enum boolean {
return $javaclassname.swigToEnum($jnicall).toBoolean();
}
%typemap(javain) enum boolean "($javainput?Boolean.TRUE:Boolean.FALSE).swigValue()"
%include "test.h"
这段代码确实有点冗长 - javain 类型映射可以简单地编写 $javainput?0:1
并且 javaout 可以同样简单,而不是完全依赖 SWIG 生成的枚举。我这样写主要是为了展示它如何与更复杂的枚举交互。所以我们可以这样写:
%module test
%{
#include "test.h"
%}
%typemap(jstype) enum boolean "boolean"
%typemap(javaout) enum boolean {
return $jnicall != 0;
}
%typemap(javain) enum boolean "$javainput?1:0"
%include "test.h"
它具有 hard-coded 始终在这里起作用的幻数,因为您明确给出了两个枚举成员值 0 和 1,但如果您不能 100% 确定这对于更通用的枚举包装来说总是正确的可能会导致一些奇怪的错误。
我之前暗示过,我们可以编写类型映射,将其作为 jboolean 从本机代码一直传递到用户使用的代理 类。这是真的,并且显然不需要沿途进行类型转换,但实际上我们可以利用现有的 SWIG 库支持 C++ bool
类型,即使使用我们的自定义枚举也是如此。 (这主要是因为从 enum boolean
-> jboolean
投射的 C 风格像我们希望的 0/1 值一样工作)。
所以我们实际上可以简单地写成:
%module test
%{
#include "test.h"
%}
%apply bool { enum boolean };
%include "test.h"
它为我们将 bool
类型映射复制到 enum boolean
类型映射中。如果出于某种原因你确实想调整 some/part 这些类型映射,你仍然可以将其用作执行此操作的基础,只需将你需要的内容更改为重要的地方。
(在这个阶段,我通过 SWIG 运行 上面的例子并检查了但没有编译输出,因为我现在没有 JDK 可以用来正确测试它)
底线:尝试所有三个建议并查看生成的 testJNI.java、test.java 和 test_wrap.c 文件以了解每个类型映射对生成的代码的影响。
我正在使用 swig 在 C 和 Java (Android) 之间创建胶水。 我在 C 中定义了一个 Boolean 类型并像这样使用: (MyGlue.h)
typedef enum boolean {
TRUE = 0x1,
FALSE = 0x0
} Boolean;
Boolean booleanValue = TRUE;
Boolean isRunning() {
return booleanValue;
}
然后在 Java 我想做以下事情:
if(MyGlue.isRunning) {
..do something..
}
我遇到的问题是 MyGlue.isRunning returns 一个 int
我可以制作一个将 int 转换为布尔值的 swig typemap 吗?
我试过以下方法,但我没有完全掌握swig typmap的用法: 在我的 swig 配置文件中添加了 follwing
%typemap(out) Boolean {
$result = boolean();
}
我没有得到我想要的东西,此外我不知道把从 int 到 boolean 的转换放在哪里,比如 (return_value != 0) 我想我需要在类型图。
是否可以用 swig 实现这种转换,所以在外部我处理布尔值而不是整数?
你在类型映射方面走在了正确的轨道上,事实上你可以使用 in/out 类型映射来做到这一点,但你还需要设置 jstype/jnitype/jtype 类型映射才能改变生成方法的签名。
一般而言,Java 类型映射存在从 C->JNI 中间体->最终 Java 类型的转换。如果您要自己编写类型映射,那么仅在 "Final Java types" 阶段执行此操作将是编写所需类型映射最少的代码的最简单位置。我整理了一个示例来向您展示那是什么样的。实际上,这意味着只更改 javain、javaout 和 jstype 类型映射:
%module test
%{
#include "test.h"
%}
%typemap(jstype) enum boolean "boolean"
%typemap(javacode) enum boolean %{
public boolean toBoolean() {
return this == TRUE;
}
%}
%typemap(javaout) enum boolean {
return $javaclassname.swigToEnum($jnicall).toBoolean();
}
%typemap(javain) enum boolean "($javainput?Boolean.TRUE:Boolean.FALSE).swigValue()"
%include "test.h"
这段代码确实有点冗长 - javain 类型映射可以简单地编写 $javainput?0:1
并且 javaout 可以同样简单,而不是完全依赖 SWIG 生成的枚举。我这样写主要是为了展示它如何与更复杂的枚举交互。所以我们可以这样写:
%module test
%{
#include "test.h"
%}
%typemap(jstype) enum boolean "boolean"
%typemap(javaout) enum boolean {
return $jnicall != 0;
}
%typemap(javain) enum boolean "$javainput?1:0"
%include "test.h"
它具有 hard-coded 始终在这里起作用的幻数,因为您明确给出了两个枚举成员值 0 和 1,但如果您不能 100% 确定这对于更通用的枚举包装来说总是正确的可能会导致一些奇怪的错误。
我之前暗示过,我们可以编写类型映射,将其作为 jboolean 从本机代码一直传递到用户使用的代理 类。这是真的,并且显然不需要沿途进行类型转换,但实际上我们可以利用现有的 SWIG 库支持 C++ bool
类型,即使使用我们的自定义枚举也是如此。 (这主要是因为从 enum boolean
-> jboolean
投射的 C 风格像我们希望的 0/1 值一样工作)。
所以我们实际上可以简单地写成:
%module test
%{
#include "test.h"
%}
%apply bool { enum boolean };
%include "test.h"
它为我们将 bool
类型映射复制到 enum boolean
类型映射中。如果出于某种原因你确实想调整 some/part 这些类型映射,你仍然可以将其用作执行此操作的基础,只需将你需要的内容更改为重要的地方。
(在这个阶段,我通过 SWIG 运行 上面的例子并检查了但没有编译输出,因为我现在没有 JDK 可以用来正确测试它)
底线:尝试所有三个建议并查看生成的 testJNI.java、test.java 和 test_wrap.c 文件以了解每个类型映射对生成的代码的影响。