我对如何正确处理JNI中的关联(或依赖)感到疑问。
让我们假设您的共享库中有2个类NativeClass1
和NativeClass2
。 NativeClass1
有一个方法void fooNative(NativeClass2* nativeObj)
,允许它使用NativeClass2
类型的对象执行某些操作。
对于这些类中的每一个,都定义了一个java类来包装相应的本机对象(JavaClass1
和JavaClass2
,每个对象都有一个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
为第一个参数)?
我想到了两种方法:
JavaClass2
。但每个人都可以访问实际的本机对象,创建另一个共享库,在delete ptr
的void指针上执行NativeClass2
或以其他方式破坏本机ojbect。
NativeClass2
对象(作为call_fooNative(...)
的第二个参数),而是传递JavaClass2
类型的实际java对象,并使用getFieldId
确定指针和getLongField
(在私有成员上发表,如Java本地接口:程良指南和规范由盛亮所述,“10.9违反访问控制规则”。在设计和安全方面哪一个是正确的方法?
答案 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的特定实例的引用。
- 不是将指针传递给NativeClass2对象(作为call_fooNative(...)的第二个参数),而是传递JavaClass2类型的实际java对象,并使用getFieldId和getLongField确定指针......
醇>
这不一定会阻止从Java访问指针。 Java代码可以use reflection to access private fields。