当前位置: 首页 > news >正文

JNI编程四:java跟JNI字符串传递

目录

  • 前言
  • 一、java层向jni层传递中文字符串的转码操作
  • 二、jni层向java层传递中文字符串的转码操作


前言

java中的中文字符使用的编码方式是根据系统默认编码方式,一般使用的是GB2312的编码方式,jni中的中文字符采用的是unicode的编码方式。所以在字符传递的时候会出现乱码情况。

一、java层向jni层传递中文字符串的转码操作

java层向jni传递中文字符的时候,我们可以利用windows.h给我们封装好的函数来操作。

JniMain.java

public class JniMain {static{System.loadLibrary("JNI_Demo1");}//----------------------向jni层传递字符串--------------------public native String chineseChars(String str);//---------------------------------------------public static void main(String[] args) {JniMain jm = new JniMain();String str = jm.chineseChars("德玛西亚"); System.out.println("java "+ str);}
}

jni_impl.c

#include "stdafx.h"#include "JniMain.h"
#include <string.h>
#include <Windows.h>/*
* Class:     JniMain
* Method:    chineseChars
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_JniMain_chineseChars
(JNIEnv * env, jobject jobj, jstring in){//iscp代表的是string转char的时候是否从新开辟的内存copy的一份jboolean iscp;char * c_str = (*env)->GetStringChars(env, in, &iscp);if (iscp == JNI_TRUE){printf("is copy: JNI_TRUE\n");}else if (iscp == JNI_FALSE){printf("is copy: JNI_FALSE\n");}int length = (*env)->GetStringLength(env, in);const jchar * jcstr = (*env)->GetStringChars(env, in, NULL);if (jcstr == NULL) {return NULL;}//jchar -> charchar * rtn = (char *)malloc(sizeof(char)* 2 * (length + 1));memset(rtn, 0, sizeof(char)* 2 * (length + 1));int size = 0;//windows提供的字符串转码的操作size = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)jcstr, length, rtn, sizeof(char)* 2 * (length + 1), NULL, NULL);/*if (size <= 0){printf("size: 0 \n", rtn);return NULL;}*/printf("jni string: %s\n", rtn);if (rtn != NULL) {free(rtn);rtn = NULL;}if (iscp == JNI_TRUE){(*env)->ReleaseStringChars(env, in, c_str);// JVM 使用。通知JVM c_str 所指的空间可以释放了}return NULL;
}

jni_impl.c的JNICALL Java_JniMain_chineseChars函数是将java层传递的字符串能转换成jni能识别的字符串。执行结果:

在这里插入图片描述


二、jni层向java层传递中文字符串的转码操作

jni层向java层传递字符串时可以使用JNIEnv所指向的结构体封装的函数来调用java中String对象封装的字符串转码功能。

jni_impl.c

#include "stdafx.h"#include "JniMain.h"
#include <string.h>
#include <Windows.h>/*
* Class:     JniMain
* Method:    chineseChars
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_JniMain_chineseChars
(JNIEnv * env, jobject jobj, jstring in){char *c_str2 = "诺克萨斯";jclass str_cls = (*env)->FindClass(env, "java/lang/String");jmethodID jmid = (*env)->GetMethodID(env, str_cls, "<init>", "([BLjava/lang/String;)V");//jstring -> jbyteArrayjbyteArray bytes = (*env)->NewByteArray(env, strlen(c_str2));// 将Char * 赋值到 bytes(*env)->SetByteArrayRegion(env, bytes, 0, strlen(c_str2), c_str2);jstring charsetName = (*env)->NewStringUTF(env, "GB2312");return (*env)->NewObject(env, str_cls, jmid, bytes, charsetName);}

其实上面的代码就是jvm反射调用java中的 new String(“诺克萨斯”,“GB2312”)



http://www.mrgr.cn/news/2568.html

相关文章:

  • 【C++】string讲解
  • 【GH】【EXCEL】P4: Chart
  • Flink 1.14.*版本kafkaSource源码
  • 文心快码 Baidu Comate 前端工程师观点分享:以文心快码 Baidu Comate为例,智能代码助手需要什么(一)
  • Nginx负载均衡调度状态
  • 多线程编程中的常见问题及解决方案
  • ES6笔记总结(Xmind格式):第一天
  • OpenCV几何图像变换(3)计算透视变换矩阵函数getPerspectiveTransform()的使用
  • 西安旅游系统--论文pf
  • ElasticSearch 相关面试题
  • linux:进程空间的回收,exec族
  • 【大模拟】逻辑回环类
  • VirtualBox上的Oracle Linux虚拟机安装Docker全流程
  • Prompt——与AI连接的桥梁
  • 【SpringBoot】10 日志持久化(log4j2)
  • WordPress Transposh WordPress Translation SQL注入漏洞
  • linux出现sql密码被忘记的解决方法
  • 【6.0】axios的高级用法
  • Apache Flink 执行过程中的四层图详解
  • 邮票孔拼版制作方法