>tree . /F
Folder PATH listing for volume D
Volume serial number is F075-351A
└───com
└───jx
com_jx_Object.cpp
com_jx_Object.hpp
com_jx_Object.obj
libobj.dll
libobj.exp
libobj.lib
Object.class
Object.java
ObjectTest.java
package com.jx; public class Object { private int index; public Object(int index) { this.index = index; } public int index() { return index; } public native int addr(); static { System.loadLibrary("libobj"); } }
>javac com\jx\Object.java
>javah -jni -d com\jx com.jx.Object
com_jx_Object.hpp:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_jx_Object */ #ifndef _Included_com_jx_Object #define _Included_com_jx_Object #ifdef __cplusplus extern "C" { #endif /* * Class: com_jx_Object * Method: addr * Signature: ()I */ JNIEXPORT jint JNICALL Java_com_jx_Object_addr (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
com_jx_Object.cpp:
#include <stdio.h> #include "com_jx_Object.hpp" JNIEXPORT jint JNICALL Java_com_jx_Object_addr (JNIEnv *env, jobject jobj) { jlong addr = reinterpret_cast<jlong>(jobj); printf("Java_com_jx_Object_addr.\n"); printf("obj addr: %ld\n", jobj); printf("obj addr: %ld\n", &jobj); printf("obj addr: %ld\n", addr); return 0; }
>cl /GR /GX /W3 /ID:\usr\bin\jdk1.8.0_101\include /ID:\usr\bin\jdk1.8.0_101\include\win32 /c /Fo.\ *.cpp
>link /DLL /OUT:.\libobj.dll .\*.obj
也可以使用以下命令一次就生成库文件
# 也可以使用以下命令一次就生成库文件: >cl /ID:\usr\bin\jdk1.8.0_101\include /ID:\usr\bin\jdk1.8.0_101\include\win32 /LD com_jx_Object.c
将生成的库文件libobj.dll放在path目录下
package com.jx; import java.lang.reflect.Field; import sun.misc.Unsafe; public class ObjectTest { public static void main(String[] args) throws Throwable { String libPath = System.getProperty("java.library.path"); System.out.println(libPath); Unsafe unsafe = getUnsafe(); Object obj = new Object(12345); Field field = Object.class.getDeclaredField("index"); long addr = location(obj); System.out.println("obj addr: " + obj.hashCode()); System.out.println("obj addr: " + addr); System.out.println("obj addr: " + unsafe.getAddress(addr)); long valueOffset = unsafe.objectFieldOffset(field); System.out.println("index offset: " + valueOffset); int value2 = unsafe.getInt(obj, valueOffset); System.out.println("index: " + value2); value2 = unsafe.getInt(addr + valueOffset); System.out.println("index: " + value2); obj.addr(); } public static long location(Object object) throws Throwable { Unsafe unsafe = getUnsafe(); Object[] array = new Object[] {object}; long baseOffset = unsafe.arrayBaseOffset(Object[].class); int addressSize = unsafe.addressSize(); long location; switch (addressSize) { case 4: location = unsafe.getInt(array, baseOffset); break; case 8: location = unsafe.getLong(array, baseOffset); break; default: throw new Error("unsupported address size: " + addressSize); } return (location); } private static Unsafe getUnsafe() throws Throwable { Class unsafeClass = Unsafe.class; for (Field f : unsafeClass.getDeclaredFields()) { if ("theUnsafe".equals(f.getName())) { f.setAccessible(true); return (Unsafe) f.get(null); } } throw new IllegalAccessException("no declared field: theUnsafe"); } }
运行结果
obj addr: 5433634 obj addr: 46840104 obj addr: 695505153 index offset: 8 index: 12345 index: 12345 Java_com_jx_Object_addr. obj addr: 10157232 obj addr: 10157172 obj addr: 10157232
冰雪魔女 2021-02-05
早安 2020-07-23
藏家011 2022-10-31
牵马的蜘蛛 2016-03-29
吟风 2017-02-03
沙落雁 2018-07-22
沙落雁 2018-06-28
沙落雁 2018-05-24
沙落雁 2017-03-20
寒江独钓 2017-03-07
藏家389 2025-03-23
藏家389 2025-03-23
藏家389 2025-03-23
藏家389 2025-03-23
藏家389 2025-03-23
藏家389 2025-03-23
藏家389 2025-03-23
藏家389 2025-03-23
藏家389 2025-03-23
藏家389 2025-03-23