2015-07-21 128 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