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

如何将Optional<Integer>与SessionID传递至JNI层原生函数?

如何通过JNI传递Java的Optional类型参数

1. 调整Java层Native方法

首先需要修改CppCreate的native方法签名,将sessionId和ttl作为参数传入:

public AuthTokenProperties(String sessionId, Optional<Integer> ttl) {                            
    m_cppRef = CppCreate(sessionId, ttl);
}
// 更新native方法,添加两个参数
private native long CppCreate(String sessionId, Optional<Integer> ttl);

2. JNI层处理Optional对象

在JNI中,我们可以借助Java反射API操作Optional对象,判断其是否包含值并提取内部的Integer值。以下是完整的JNI实现代码:

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jlong JNICALL
Java_AAuthenticationService_CppCreate(JNIEnv *env, jobject jniAuthService, jstring sessionId, jobject ttlOptional)
{
    // 转换sessionId为C++字符串
    const char* sessionCStr = env->GetStringUTFChars(sessionId, nullptr);
    std::string sessionStr(sessionCStr);
    env->ReleaseStringUTFChars(sessionId, sessionCStr);

    // 获取Optional类的引用
    jclass optionalCls = env->FindClass("java/util/Optional");
    // 获取isPresent()方法ID,用于判断是否有值
    jmethodID isPresentId = env->GetMethodID(optionalCls, "isPresent", "()Z");
    jboolean hasValue = env->CallBooleanMethod(ttlOptional, isPresentId);

    jint ttlVal = -1; // 根据业务需求设置空值时的默认值
    if (hasValue) {
        // 获取get()方法ID,取出内部对象
        jmethodID getId = env->GetMethodID(optionalCls, "get", "()Ljava/lang/Object;");
        jobject ttlObj = env->CallObjectMethod(ttlOptional, getId);
        
        // 将Integer对象转换为int值
        jclass integerCls = env->FindClass("java/lang/Integer");
        jmethodID intValId = env->GetMethodID(integerCls, "intValue", "()I");
        ttlVal = env->CallIntMethod(ttlObj, intValId);

        // 释放局部引用,避免内存泄漏
        env->DeleteLocalRef(ttlObj);
        env->DeleteLocalRef(integerCls);
    }

    // 释放Optional类的局部引用
    env->DeleteLocalRef(optionalCls);

    // 此处替换为你的C++业务逻辑,返回对应对象的指针
    // 示例:return (jlong)new AuthTokenCppImpl(sessionStr, hasValue ? ttlVal : -1);
    return 0; // 临时返回值,需替换为实际内容
}

关键注意事项

  • 局部引用管理:JNI中通过FindClass、CallObjectMethod获取的局部引用,建议显式调用DeleteLocalRef释放,防止内存泄漏。
  • 默认值适配:当Optional为空时,要根据业务场景设置合理的默认值,或者在C++层使用std::optional<int>来接收,保持类型一致性。
  • 方法签名校验:JNI方法签名必须与Java层完全匹配,可通过javap -s java.util.Optional命令查看Optional类的方法签名,确保调用正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 07:25:26