JNI静态内部类native方法接收long类型传入参数值异常问题求助
问题根因及解决方案
- 第一个核心错误:没有在C实现文件中引入javah自动生成的JNI头文件
如果没有引入对应头文件,C编译器会对该JNI函数做隐式声明处理:默认所有参数的类型为int,同时不会正确处理JNIEXPORT、JNICALL宏对应的平台调用约定(比如Windows下的stdcall规则、Linux下的动态库符号导出规则)。调用约定不匹配会直接导致参数栈读取完全错乱,就是你遇到的三个参数值异常、甚至完全相同的核心原因。
修复方案:在C实现代码的最开头引入你用javah生成的头文件,示例:
#include "api_A.h" // 替换为你实际生成的头文件名 #include <stdio.h>
- 第二个错误:打印
jlong的格式符不匹配jlong是JNI定义的跨平台64位有符号整数,不同平台对应的C原生类型不同:32位系统下对应long long,64位Linux下对应long,Windows下对应__int64。你直接用%x打印,%x仅适配32位无符号整数,读取长度不对,自然会输出错误值,甚至会因为参数栈偏移错误影响后续变量的打印结果。
修复方案:引入<inttypes.h>头文件,用适配64位整数的格式符打印:
#include <inttypes.h> // 打印jlong的正确写法 printf("%" PRIx64 "\n", (uint64_t)x);
- 其他需要检查的配置项:
- 如果你用C编译器编译JNI实现,确保函数声明被
extern "C"包裹,否则C的名字修饰规则会导致JNI运行时找不到对应的native函数。javah生成的头文件已经自带了extern "C"的条件编译包裹,只要正确引入头文件就不会有这个问题。 - 确认编译出来的动态库(.so/.dll/.dylib)架构和你运行的JVM架构完全匹配,32位JVM加载64位库、或者反过来都会出现参数读取异常的问题。
- 每次修改C代码后务必重新编译动态库,并且替换JVM实际加载的库文件,避免运行的是旧版本的错误代码。
- 如果你用C编译器编译JNI实现,确保函数声明被
内容的提问来源于stack exchange,提问作者Aviv David
相关产品推荐
相关产品推荐

