C++ アプリケーションを Java に移植しています。SWIG を使用して、いくつかの Java クラスと JNI ラッパーを生成しました。
C++ には、Animal を拡張して Killable を実装する Lion というクラスがあります。Java には多重継承が存在しないという警告が表示されました。今のところ問題ありません。Lion は私の Java クラスで Animal を拡張するだけです。
SWIG で生成されたクラス:
public class Killable {
private long swigCPtr;
protected boolean swigCMemOwn;
public Killable(long cPtr, boolean cMemoryOwn) {
swigCMemOwn = cMemoryOwn;
swigCPtr = cPtr;
}
protected static long getCPtr(Killable obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
protected void finalize() {
delete();
}
public synchronized void delete() {
if (swigCPtr != 0) {
if (swigCMemOwn) {
swigCMemOwn = false;
cppinterfaceJNI.delete_Killable(swigCPtr);
}
swigCPtr = 0;
}
}
public long getKillableId() {
return cppinterfaceJNI.Killable_getId(swigCPtr, this);
}
public void kill() {
cppinterfaceJNI.Killable_kill(swigCPtr, this);
}
}
public class Lion extends Animal {
private long swigCPtr;
public Lion(long cPtr, boolean cMemoryOwn) {
super(cppinterfaceJNI.Lion_SWIGUpcast(cPtr), cMemoryOwn);
swigCPtr = cPtr;
}
public static long getCPtr(Lion obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
...
}
ここで、Killable の配列が必要だとしましょう。SWIG で生成された Java クラスは元の c++ クラスへのポインターを格納するため、次のようなことができるはずです。
LinkedList<Killable> list = new LinkedList<Killable>();
Killable k = new Killable(Lion.getCPtr(myLionObject), false);
list.add(k);
System.out.println(k.getKillableId()) // Return a long, no crash here but I got a huge number (wrong number)
k.kill(); // Crash
それを行ってもエラーはありませんが、オブジェクト k のメソッドにアクセスしようとすると、ライブラリがクラッシュします。適切な実装が見つからないためにクラッシュが発生したと思いますが、新しいオブジェクトへの有効なポインターを与えるため、理由がわかりません。クラッシュが発生する理由や、ここで使用できる回避策はありますか?
ご協力いただきありがとうございます