处理与JNI的关联

时间:2015-07-21 20:34:26

标签: java c++ pointers java-native-interface

我对如何正确处理JNI中的关联(或依赖)感到疑问。

让我们假设您的共享库中有2个类NativeClass1NativeClass2NativeClass1有一个方法void fooNative(NativeClass2* nativeObj),允许它使用NativeClass2类型的对象执行某些操作。

对于这些类中的每一个,都定义了一个java类来包装相应的本机对象(JavaClass1JavaClass2,每个对象都有一个long私有成员指向一个动态分配的本机分别为NativeClass1NativeClass2类型的对象。

我希望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为第一个参数)?

我想到了两种方法:

  1. JavaClass2
  2. 中的长指针创建公共getter方法

    但每个人都可以访问实际的本机对象,创建另一个共享库,在delete ptr的void指针上执行NativeClass2或以其他方式破坏本机ojbect。

    1. 不是将指针传递给NativeClass2对象(作为call_fooNative(...)的第二个参数),而是传递JavaClass2类型的实际java对象,并使用getFieldId确定指针和getLongField(在私有成员上发表,如Java本地接口:程良指南和规范由盛亮所述,“10.9违反访问控制规则”。
    2. 在设计和安全方面哪一个是正确的方法?

1 个答案:

答案 0 :(得分:0)

  

如何从JavaClass2获取底层长指针(到NativeClass2)成员以调用void JavaClass1 :: call_fooNative(long nativeObject1Ptr,long nativeObject2Ptr)(假设您将NativeClass1的指针作为第一个参数传递)?

您的第一种方法可能是合理的。这是SWIG使用的方法。

SWIG是一个开源工具,可为C ++代码生成Java包装器。如果你要包装很多类或方法,你可能需要考虑使用它。

例如,这里是SWIG生成的一些代码(更改了类名):

vstest.console.exe C:\Code\SampleReportsProject\SampleReportsProject\bin\Debug\SampleReportsProject.dll
  

但是每个人都可以访问实际的本机对象,创建另一个共享库,在NativeClass2的void指针上执行delete ptr或以其他方式破坏本机对象。

不一定是每个人 - 只有Java和本机代码可以访问对NativeClass2的特定实例的引用。

  
      
  1. 不是将指针传递给NativeClass2对象(作为call_fooNative(...)的第二个参数),而是传递JavaClass2类型的实际java对象,并使用getFieldId和getLongField确定指针......
  2.   

这不一定会阻止从Java访问指针。 Java代码可以use reflection to access private fields