2017-02-17 26 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