jni中的NewStringUTF这个函数调用后需要释放内存吗?

今天开发中遇到一个需求:java调用.so或dll动态库里的方法后需要返回一个字符串给java使用,如以下方式:

JNIEXPORT jstring JNICALL Java_com_ygc_demo_jni_ApiNative_fromCharToJString(JNIEnv *, jclass);

请注意了这里返回的是一个jstring,那我们怎么返回这个java想要的string呢?这里就用到了jni里的NewStringUTF这个函数,具体的实现如下:

JNIEXPORT jstring JNICALL Java_com_ygc_demo_jni_ApiNative_fromCharToJString
  (JNIEnv *env, jclass jc){
	char Version[256] = {"Hello world!"};
	jstring value = 	env->NewStringUTF((const char*)Version);
	return value;
}

代码很简单不用解释,这里主要说的是NewStringUTF创建后返回的jstring要不要释放内存的问题,刚开始我也纠结这个问题我的办法就是在java层写了个while(true){}的循环测试下到底内存是否出现问题,结果跑了一个上午程序依然正常使用,我的结论就是调用NewStringUTF之后返回是jstring不需要释放,java的虚拟机会自动释放这个内存,这个只是我的一个小测试,我又去openJdk里去搜索这种返回jstring用法的代码结果搜索后openJdk里也没有释放内存的操作,代码如下:

/*
 * Class:     sun_security_mscapi_Key
 * Method:    getKeyType
 * Signature: (J)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_security_mscapi_Key_getKeyType
  (JNIEnv *env, jclass jclazz, jlong hCryptKey)
{
    ALG_ID dwAlgId;
    DWORD dwAlgIdLen = sizeof(ALG_ID);

    if (::CryptGetKeyParam((HCRYPTKEY) hCryptKey, KP_ALGID, (BYTE*)&dwAlgId, &dwAlgIdLen, 0)) {

        if (CALG_RSA_SIGN == dwAlgId) {
            return env->NewStringUTF("Signature");

        } else if (CALG_RSA_KEYX == dwAlgId) {
            return env->NewStringUTF("Exchange");

        } else {
            char buffer[64];
            if (sprintf(buffer, "%lu", dwAlgId)) {
                return env->NewStringUTF(buffer);
            }
        }
    }

    return env->NewStringUTF("<Unknown>");
}

代码二:

JNIEXPORT jstring JNICALL 
Java_com_sun_java_util_jar_pack_NativeUnpack_getOption(JNIEnv *env, jobject pObj, 
				       jstring pProp) {

  unpacker*   uPtr  = get_unpacker(env, pObj);
  CHECK_EXCEPTION_RETURN_VALUE(uPtr, NULL);
  const char* prop  = env->GetStringUTFChars(pProp, JNI_FALSE);
  CHECK_EXCEPTION_RETURN_VALUE(prop, NULL);
  const char* value = uPtr->get_option(prop);
  CHECK_EXCEPTION_RETURN_VALUE(value, NULL);
  env->ReleaseStringUTFChars(pProp, prop);
  return env->NewStringUTF(value);
}

结论:综合上面我的测试和在openJdk里搜索的使用方法得出的结论,NewStringUTF之后的返回给java层的jstring不需要释放内存,但是局部使用的不返回给java层的建议还是调用下env->DeleteLocalRef(jstring);

如果我以上分析的结论或方法有误的还请大牛提出我会及时改正,感谢你们查看我的文章。

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一段JNI接口register_JPG_callback(callback)注册回调函数并在Java调用的示例代码: ```c++ #include <jni.h> // 定义回调函数类型 typedef void (*JPG_callback)(const char*); // 定义全局变量存储回调函数 JPG_callback g_JPG_callback = NULL; // 注册回调函数 JNIEXPORT void JNICALL Java_com_example_MyClass_register_1JPG_1callback(JNIEnv* env, jobject obj, jobject callback) { // 获取回调函数对象的类和方法ID jclass callbackClass = env->GetObjectClass(callback); jmethodID callbackMethodID = env->GetMethodID(callbackClass, "onJPGCallback", "(Ljava/lang/String;)V"); // 将回调函数对象转为全局引用,以便在回调函数使用 jobject globalCallback = env->NewGlobalRef(callback); // 将回调函数保存到全局变量 g_JPG_callback = [env, globalCallback, callbackMethodID](const char* data) { jstring jdata = env->NewStringUTF(data); env->CallVoidMethod(globalCallback, callbackMethodID, jdata); env->DeleteLocalRef(jdata); }; } // 调用回调函数 void call_JPG_callback(const char* data) { if (g_JPG_callback != NULL) { g_JPG_callback(data); } } ``` 在Java调用register_JPG_callback(callback)方法注册回调函数: ```java public class MyClass { // 定义回调函数接口 public interface JPGCallback { void onJPGCallback(String data); } // 注册回调函数 public native void register_JPG_callback(JPGCallback callback); // 调用回调函数 private void onJPGCallback(String data) { // 处理回调函数 } // 加载动态库 static { System.loadLibrary("native-lib"); } // 在某个方法注册回调函数 public void registerJPGCallback() { register_JPG_callback(new JPGCallback() { @Override public void onJPGCallback(String data) { onJPGCallback(data); } }); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值