2015-07-21 83 views
1

我有關於如何在JNI中正確處理關聯(或依賴關係)的問題。處理與JNI的關聯

讓我們假設在你的共享庫中你有2個類,NativeClass1NativeClass2NativeClass1有一個方法void fooNative(NativeClass2* nativeObj),它允許它用NativeClass2類型的對象執行一些操作。

對於每個類,Java類被定義爲包相應的天然對象(JavaClass1JavaClass2,每一個具有long私有成員分別指向NativeClass1類型和NativeClass2的一個動態分配的本地對象,)。

我想JavaClass1也有一個方法public void fooJava(JavaClass2 obj)(以及相應的本地方法private native void call_fooNative(long nativeObject1Ptr, long nativeObject2Ptr)其鑄造指針後最終將調用NativeClass1::void fooNative(NativeClass2* nativeObj))。

你將如何獲得潛在的長指針(到NativeClass2)成員從JavaClass2爲了調用void JavaClass1::call_fooNative(long nativeObject1Ptr, long nativeObject2Ptr)(假設你傳遞給NativeClass1的指針作爲第一個參數)?

我想到的2種方法:

  1. 創建從JavaClass2長指針一個公共的getter方法。

但每個人都可以有機會獲得實際的原生對象,創建另一個共享庫,對NativeClass2的空指針進行delete ptr或以其他方式破壞原生ojbect。

  • 代替使指針NativeClass2對象(如從call_fooNative(...)第二個參數,通JavaClass2類型的實際的Java對象,並使用getFieldIdgetLongField確定指針(其permited一個私有成員上,如Java本機接口說:程序員指南和規格盛梁啓超「10.9違反訪問控制規則」
  • 哪一個會在設計和安全方面的正確方法

    回答

    0

    爲了調用void JavaClass1 :: call_fooNative(long nativeObject1Ptr,long nativeObject2Ptr)(假設你將一個指向NativeClass1的指針作爲第一個參數),你將如何從JavaClass2獲取底層長指針(到NativeClass2)成員?

    您的第一個方法可能是合理的。這是SWIG使用的方法。

    SWIG是一個爲C++代碼生成Java包裝的開源工具。如果你包裝了很多類或方法,你可能要考慮使用它。

    例如,這裏是由痛飲生成的一些代碼(用類名稱變更):

    public class Foo { 
        private long swigCPtr; 
        protected boolean swigCMemOwn; 
    
        public Foo(long cPtr, boolean cMemoryOwn) { 
        swigCMemOwn = cMemoryOwn; 
        swigCPtr = cPtr; 
        } 
    
        public static long getCPtr(Foo obj) { 
        return (obj == null) ? 0 : obj.swigCPtr; 
        } 
    
        ... 
    

    但每個人都可以有機會獲得實際的原生對象,創建另一個共享庫,執行刪除PTR在NativeClass2的void指針上或以其他方式損壞本地對象。

    不一定每個人 - 只需要Java和本地代碼即可訪問對特定NativeClass2實例的引用。

  • 代替使指針NativeClass2對象(從call_fooNative(第二個參數...),通式JavaClass2的實際Java對象,並確定與該指針getFieldId和getLongField ...
  • 這不一定會阻止訪問從Java,Java代碼的指針可以use reflection to access private fields

    +0

    好吧,那我就用我的第一個方法去。謝謝你的細節! – danimihalca