java - Swig 如何定义一个类型映射,将 C 类型定义的 boolean 值转换为 java boolean 值

标签 java android c swig typemaps

我正在使用 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 返回一个 int

我可以制作一个将 int 转换为 boolean 值的 swig 类型映射吗?

我尝试了以下方法,但我没有完全掌握 swigtymap 的用法: 在我的 swig 配置文件中添加了以下内容

%typemap(out) Boolean {
    $result = boolean($1);
}

我没有得到我想要的,此外我不知道在哪里放置从 int 到 boolean 的转换,例如 (return_value != 0),我想我需要在类型映射中的某个位置指定。

是否可以使用 swig 实现此转换,以便在外部处理 boolean 值而不是整数?

最佳答案

您的类型映射走在正确的轨道上,事实上您可以使用输入/输出类型映射来完成此操作,但您还需要设置 jstype/jnitype/jtype 类型映射,以便更改生成的签名方法。

一般来说,Java 类型映射存在从 C->JNI 中间类型->最终 Java 类型的转换。如果您要自己编写类型映射,那么在“最终 Java 类型”阶段执行它将是编写所需类型映射最少的代码的最简单位置。我整理了一个例子来向您展示那是什么样的。实际上,这意味着仅更改 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"

它具有硬编码的魔数(Magic Number),在这里始终有效,因为您明确给出了两个枚举成员值 0 和 1,但如果您不能 100% 确定这对于更一般的枚举包装来说总是正确的,可能会导致一些问题奇怪的错误。

我之前暗示过,我们可以编写类型映射,将其作为 jboolean 一直从 native 代码传递到用户使用的代理类。这是事实,并且显然不需要任何类型转换,但实际上我们可以利用现有的 SWIG 库对 C++ bool 类型的支持,即使使用我们的自定义枚举也是如此。 (这主要是因为从 enum boolean -> jboolean 进行的 C 风格转换可以按照我们希望的 0/1 值工作)。

所以我们实际上可以简单地写:

%module test 

%{
#include "test.h"
%}

%apply bool { enum boolean };

%include "test.h"

它将 bool 类型映射复制到 enum boolean 类型映射中。如果出于某种原因您确实想要调整这些类型映射的某些/部分,您仍然可以使用它作为执行此操作的基础,并将您需要的内容更改为重要的地方。

(在此阶段,我已通过 SWIG 运行上述示例并检查但未编译输出,因为我现在没有 JDK 来正确测试它)

底线:尝试所有三个建议,并查看生成的 testJNI.java、test.java 和 test_wrap.c 文件,以了解每个类型映射对生成的代码有什么影响。

关于java - Swig 如何定义一个类型映射,将 C 类型定义的 boolean 值转换为 java boolean 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42301700/

相关文章:

c - 一个更好的计算数字平方根的程序

c++ - 没有匹配的函数可调用 'SDL_UpperBlit'

java - 确定在 java 中打印到输出流的字符数

java - 面向用户的数字 : implementing them efficient, "operational"和四舍五入安全吗?

java - 如何检测Android手机的方向从水平位置到垂直位置的变化?

android - 相对布局运行时的位置 View

android - 我们可以在通知中发送 Firebase ServerValue 时间戳吗?

java - Spring AOP 复杂切入点

java - 使用带有文件类扩展名的 File.listFiles()

java - JFileChooser - 在当前目录中打开