在c/c++中获取java对象的内存地址

Posted

技术标签:

【中文标题】在c/c++中获取java对象的内存地址【英文标题】:get memory address of java object in c/c++ 【发布时间】:2017-11-13 09:36:25 【问题描述】:

假设我有一个 java 类

class NativeInterface
    public static native void access(Object obj);

而我要做的就是访问该对象的第二个字节(例如)。

即我想做这样的事情:

#include<jni.h>
#include "NativeInterface.h"
#include <stdio.h>

using byte = unsigned char;

/*
* Class:     NativeInterface
* Method:    access
* Signature: (Ljava/lang/Object)V
*/
JNIEXPORT void JNICALL Java_NativeInterface_access(JNIEnv* env, jclass _obsolete, jobject obj)
    byte byte_array[] = obj;
    printf("%c",byte_array[2]);

现在显然,这行不通。 obj 甚至可能不是 java 对象。 (jobject 定义在 jni.h 中,我还没有弄清楚它的作用。)

那么我该怎么做呢?

(尝试这种幼稚的尝试将导致

error: initializer fails to determine size of ‘byte_array’
     byte byte_array[] = obj;
                         ^~~~

,顺便说一句。)

【问题讨论】:

你不能分配给一个数组,也不能用不同于数组初始化器的东西来初始化它!请查阅您的文档,jobject 到底是什么char *objbytes = obj 之类的东西可能会起作用。 【参考方案1】:

obj 甚至可能不是 java 对象”

你几乎自己想通了。它只是比那强一点。 Java有垃圾收集。仅出于这个原因,您就知道obj 不是 java 对象,而只是一个句柄,它在垃圾收集器在内存中随机播放时引用该对象。

您现在看到了问题中的根本缺陷:“获取 java 对象的内存地址”假定您获得了有用的值。但即使你能得到一个地址,从你得到它的第一个时钟滴答开始,它也是不可靠的。

【讨论】:

我同意它不是 java 对象,我不同意如果我能得到一个地址,那将是“从第一个时钟开始就不可靠”。请参阅我的后续问题:***.com/questions/47267806/… @User1291:您正在查看幕后 JNI 代码,该代码可防止对象在 JNI 分配 Int 时移动。 我不明白你的意思。如果你是正确的,那么不安全的实现如何在执行时不做任何事情来“防止对象移动”? @User1291:这是另一个不正确的假设。 JNI 是 JVM 的组成部分,它确实可以防止对象移动。这并不奇怪,JVM 必须阻止对象移动,无论谁在对象上调用方法。 谢谢。我试图最终在 RTM 事务中执行它是否重要(请参阅***.com/questions/47220275/how-to-use-unsafe-in-jni)?我不完全确定,但我假设在获取地址的过程中读取的至少一个值将不得不在移动中改变,s.t.事务中止并且可以重试。因此,如果我们在同一事务中以事务方式解析地址并访问/修改位置……那应该可行吗?

以上是关于在c/c++中获取java对象的内存地址的主要内容,如果未能解决你的问题,请参考以下文章

如何获得java对象的内存地址

如何获取到JAVA对象所在的内存地址

java是传值还是传引用

java对象的内存布局:利用sun.misc.Unsafe获取类字段的偏移地址和读取字段的值

java获取浏览器地址栏地址

python的变量,对象的内存地址以及参数传递过程