Java JNI将长值传递给本机方法

Java JNI将长值传递给本机方法,java,c++,java-native-interface,javaagents,jvmti,Java,C++,Java Native Interface,Javaagents,Jvmti,因此,如上所述,我试图在不安全的帮助下将int对象复制到堆外内存中。以下是我的主要功能: public static void main(String[] args) throws Exception { UnsafeHelper hlpr = new UnsafeHelper(); int original = 100; long copyaddress = hlpr.shallowCopy(original); System.out.println("COP

因此,如上所述,我试图在不安全的帮助下将int对象复制到堆外内存中。以下是我的主要功能:

public static void main(String[] args) throws Exception {
    UnsafeHelper hlpr = new UnsafeHelper();

    int original = 100;
    long copyaddress = hlpr.shallowCopy(original);
    System.out.println("COPIED TO ADDRESS: " + copyaddress);
    int copy = (int) hlpr.fromAddress(copyaddress);

    getCopiedObject(copyaddress);
}
它为我提供复制对象开头的地址(
copyaddress

接下来,我想把这个地址传递给jni代理中定义的函数。以下是java类中本机函数的声明:

私有静态本机void getCopiedObject(长地址)

以下是agent.h中函数的声明:

JNIEXPORT void JNICALL Java_main_main_getCopiedObject(JNIEnv*,jlong)

这就是我遇到麻烦的地方。。。我在C++函数中得到的长值与我在java中传递的值不同……
JNIEXPORT void JNICALL Java_main_Main_getCopiedObject(JNIEnv *env, jlong address){
    ...
    unsigned long long a = address;
    signed long long b = address;
    printf("UNSIGNED LONG LONG %llu \n", a);
    printf("SIGNED LONG LONG %lld \n", b);
    ...
}

我的例子是java长的64位,所以我在C++代码中使用<代码> long long <代码>…我尝试了有符号和无符号转换,但都不起作用

因此,当我运行此代码时,我得到以下输出:

JAVA:
COPIED TO ADDRESS: 1487190592 
AGENT:
UNSIGNED LONG LONG 37025744 
SIGNED LONG LONG 37025744 
根据输出,我以错误的方式将jlong转换为long


有人知道如何从
jlong
中获取正确的
long
值吗?

我似乎已经找到了问题所在。当您有一个
静态本机
方法时,除了Java中的参数外,还有两个额外的参数。第一个是
JNIEnv
,第二个是
jclass

我不知道您是如何生成
.h
文件的,但当我使用时:

javah -jni Main
我得到签名:

JNIEXPORT void JNICALL Java_Main_passLong(JNIEnv *, jclass, jlong);
.h
文件中。如果我这样使用它,它的行为与预期的一样。因此,我的解决方案是在
jlong
之前添加
jclass
参数


如果删除
jclass
参数,我会看到错误的值。我猜JVM在加载库时不会检查本机方法的签名。

我无法复制。你可以发布一个。为什么Java方法有2个参数,而C函数有1个?@Jornverne,我已经编辑了我的帖子,希望我的问题现在会更清楚。@user2543253,忘了重构我的代码一点,但现在我做对了,编辑了代码。