Swig如何定义一个将C typedefined Boolean转换为java boolean的typemap

时间:2017-02-17 15:31:49

标签: java android c swig typemaps

我使用swig在C和Java(Android)之间创建了一个粘合剂。 我在C中定义了一个类型布尔值并使用如下:  (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转换为布尔值的swig类型映射吗?

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

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

我没有得到我想要的东西,除了我不知道在哪里将转换从int转换为boolean(return_value!= 0),我想我需要在typemap中指定某处。

是否有可能通过swig实现这种转换,所以外部我处理的是布尔值而不是整数?

1 个答案:

答案 0 :(得分:3)

你在使用输入/输出类型地图的正确轨道上,但实际上你可以使用输入/输出类型地图,但你也需要设置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"

其中有硬编码的魔术数字总是可以在这里工作,因为你明确地给出了两个枚举成员值为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字体图中。如果出于某种原因你想要调整部分/部分这些类型图,你仍然可以使用它作为执行此操作的基础,只需将所需内容更改为重要的位置。

(在这个阶段我通过SWIG运行上面的例子并检查但没有编译输出,因为我现在还没有JDK可以正确地进行测试)

结论:尝试所有三个建议并查看生成的testJNI.java,test.java和test_wrap.c文件,以了解每个typemap对生成的代码的影响。