sol*_*tim 2 java-native-interface
美好的一天,主人.假设我有一个java类A:
class A {
public A() {}
public native void setValue(String value);
public native String getValue();
}
Run Code Online (Sandbox Code Playgroud)
实现本机C代码时,全局char []变量用于存储仅由本机setValue方法设置的值.该getValue方法只返回该全局char []变量.
我的问题出现了:我创建了几个A对象,并调用它们各自的set/get方法,我发现它们最终会写入并读取相同的内存块!实际上,C本机代码中的全局char []变量完全由所有A对象共享.
有人能给我一些深入解释这种行为吗?我知道我在JNI的工作方式上有一个基本的误解.谢谢!
问题是你的一方面是面向对象的java,另一方面是程序C.当加载java类A时,JNI不会以某种方式在C世界中创建对象(这是C - 而不是C++),没有对象到对象的映射.所以JNI加载在C世界对应的CPP文件一旦到内存中(这是用C完全正常的行为).编译器看到一堆函数和一个全局引用,不需要以某种方式创建多个实例.加载Java类时,所有JNI编译器都将C文件添加到要编译的文件列表中.
您希望拥有Java对象和C对象之间的映射.这可以通过几种方式实现,我建议你阅读JNI中的代理模式.
为了解释很快,您有两种基本方法来实现这一目标.您可以在C端或Java端执行此操作.在C世界中存储关系时,您将在C中维护一个哈希表,其中C对象映射到Java对象.反过来说,你会在Java对象中有一个int对象,它实际上是指向内存中C对象的指针.在C代码中,您将取消引用此指针(通过GetIntField())并转换为您需要的C对象.
当然补充
private String value;
Run Code Online (Sandbox Code Playgroud)
对你的Java类A来说,确实非常顺畅.Java有一个对象的概念,所以你可以从C世界访问这些字符串
env->GetObjectField(obj, "value", "Ljava/lang/String;")
Run Code Online (Sandbox Code Playgroud)
env是JNI环境.
| 归档时间: |
|
| 查看次数: |
2613 次 |
| 最近记录: |