2017-02-17 88 views
2

我正在使用swig在C和Java(Android)之间创建粘合。 我在C中定义一个布尔类型像这样使用: (MyGlue.h)Swig如何定义将C typedefined布尔转换为java的类型映射布尔

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 typemap吗?

我曾尝试以下,但我并没有完全掌握了一大口typmap的用法: 在我痛饮配置文件中添加的follwing

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

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

是否有可能通过swig实现这种转换如此外在的处理布尔值而不是整数?

回答

2

你在类型图的正确轨道上,实际上你可以用in/out typemaps来做,但是你也需要设置jstype/jnitype/jtype typemaps以改变签名生成的方法。

通常在Java类型映射中,有一个从C-> JNI intermediate-> Final Java类型的转换。如果您自己编写一个类型映射,那么只需在“最终Java类型”阶段执行就可以用最少的类型映射编写代码。我已经举了一个例子来告诉你这是什么。在实践中它意味着改变只是javain,javaout和jstype typemaps:

%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根本就生成了enum。我是这样写的,主要是为了展示它如何与更复杂的枚举进行交互。因此,我们可以这样写:

%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 typemaps为enum boolean typemaps我们。如果无论出于何种原因你想调整这些类型图的某些/部分,你仍然可以将其作为做这件事的基础,并且只需要改变你需要的地方。

(在这个阶段,我已经运行通过痛饮上面的例子和检查,但没有编制的输出,因为我没有JDK的正确,现在对其进行测试以手)

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

+0

工作就像一个魅力! – alexm