SWIG内存管理
?每個(gè)由SWIG產(chǎn)生的代理類,擁有一個(gè)所屬標(biāo)記(swigCMeOwn).這個(gè)標(biāo)記指定該有誰清理這個(gè)優(yōu)先的C/C++組件。如果代理類有這個(gè)組件,這個(gè)內(nèi)存將會(huì)得到釋放通過finalize方法,當(dāng)它被當(dāng)做垃圾回收。僅僅通過觸發(fā)delete函數(shù)沒有等待垃圾回收下內(nèi)存得到釋放。在運(yùn)行期間這個(gè)Java類能夠被指導(dǎo)來釋放或獲得C/C++組件的ownership通過swigReleaseOwnerShip和swigTakeOwnership函數(shù)。
? 本地代碼調(diào)用Java
?直到這,已經(jīng)知道了從Java到C/C++代碼。在這些情況下,你可能需要從C/C++代碼返回到Java代碼,例如回調(diào)。SWIG并提供支持從C/C++代碼到Java通過虛函數(shù)。
? 匿名的通信:
為了展示這個(gè)過程,你將轉(zhuǎn)化這個(gè)getuid函數(shù)調(diào)用到一個(gè)匿名的模式通過封裝它在一個(gè)C/C++類中和返回它的結(jié)果通過一個(gè)回調(diào)。對(duì)于這個(gè)例子,放在類的定義和指定在.i的接口文件,如下:
%module Unix
. . .
%{
/* Asynchornous user ID provider. */
class AsyncUidProvider {
public:
AsyncUidProvider() {
}
virtual ~ AsyncUidProvider() {
}
void get() {
onUid(getuid());
}
virtual void onUid(uid_t uid) {
}
public:
AsyncUidProvider();
virtual ~ AsyncUidProvider();
void get();
virtual void onUid(uid_t uid);
};
允許的指揮:
SWIG提供對(duì)于交叉語言polymorphism的支持。這個(gè)directors功能默認(rèn)關(guān)閉。為了開啟它,這%module預(yù)處理應(yīng)該被修改包含directors標(biāo)記。在開啟了directors擴(kuò)展后,這個(gè)功能應(yīng)用在AsynUidProvider類使用%feature預(yù)處理指令。所有的改變?nèi)缦?#xff1a;
/* Module name is Unix. */
%module(directors = 1) Unix
/* Enable directors for AsyncUidProvider. */
%feature("director") AsyncUidProvider;
開啟RTTi
默認(rèn)情況下,RTTI被Android NDK建立系統(tǒng)關(guān)閉。為了使用它,修改Android.mk文件,如下:
# Enable RTTI
LOCAL_CPP_FEATURES + = rtti
覆蓋這個(gè)回調(diào)函數(shù)
在Java一邊,你需要擴(kuò)展這暴露的AsyncUidProvider類和覆蓋著onUid方法來接收getuid函數(shù)調(diào)用的結(jié)果,如下:
package com.example.hellojni;
import android.widget.TextView;
import com.apress.swig.AsyncUidProvider;
public class UidHandler extends AsyncUidProvider {
private final TextView textView;
UidHandler(TextView textView) {
this.textView = textView;
}
@Override
public void onUid(long uid) {
textView.setText("UID: " + uid);
}
}
更新項(xiàng)目:
@Override
public void onCreate(Bundle savedInstanceState)
{
. . .
TextView tv = new TextView(this);
setContentView(tv);
UidHandler uidHandler = new UidHandler(tv);
uidHandler.get();
總結(jié)