You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用javac生成名称稳定的头文件(避免函数名含1)

解决JNI头文件函数名自动插入"1"的问题
  • 原因分析:JNI的命名规则里,下划线_是用来分隔包名、类名和方法名的特殊字符。当Java native方法名本身包含下划线时,javac会自动将方法名里的下划线转义为_1,避免和分隔符混淆,所以生成的头文件函数名会出现_1。

  • 解决方案1:修改Java方法名(推荐)
    直接移除native方法名中的下划线,改用Java标准的驼峰命名法,示例:

    package examples.logging;
    
    public class FastLogging {
        public static native long loggingNew(int level, String domain, boolean console, String file, String server,
                String connect, int max_size, int backlog);
    
        public static native void loggingSetLevel(long instance_ptr, int level);
        // ...
    }
    

    重新执行javac -h . examples/logging/FastLogging.java,生成的头文件函数名将变为Java_examples_logging_FastLogging_loggingNew和Java_examples_logging_FastLogging_loggingSetLevel,不会再出现_1。

  • 解决方案2:使用JNI动态注册(兼容原有方法名)
    如果需要保留原有Java方法名的下划线,可通过JNI动态注册的方式绑定方法,无需遵循自动生成的命名规则:

    1. 编写JNI实现函数时自定义函数名,比如:
      #include <jni.h>
      
      JNIEXPORT jlong JNICALL native_logging_new(JNIEnv *env, jclass clazz, jint level, jstring domain, jboolean console, jstring file, jstring server, jstring connect, jint max_size, jint backlog) {
          // 你的实现逻辑
          return 0;
      }
      
      JNIEXPORT void JNICALL native_logging_set_level(JNIEnv *env, jclass clazz, jlong instance_ptr, jint level) {
          // 你的实现逻辑
      }
      
    2. 在JNI_OnLoad函数中注册方法映射:
      static const JNINativeMethod methods[] = {
          {"logging_new", "(ILjava/lang/String;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;II)J", (void *)native_logging_new},
          {"logging_set_level", "(JI)V", (void *)native_logging_set_level}
      };
      
      JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
          JNIEnv *env;
          if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) != JNI_OK) {
              return JNI_ERR;
          }
          jclass clazz = (*env)->FindClass(env, "examples/logging/FastLogging");
          if (clazz == NULL) {
              return JNI_ERR;
          }
          if ((*env)->RegisterNatives(env, clazz, methods, sizeof(methods)/sizeof(methods[0])) < 0) {
              return JNI_ERR;
          }
          return JNI_VERSION_1_6;
      }
      

    这种方式下,Java方法名无需修改,也能正常和JNI函数绑定。

内容的提问来源于stack exchange,提问作者Martin Bammer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 19:18:34