JAVA源码:
package com.fmy;
import java.io.UnsupportedEncodingException;
public class FMY {
static{
System.loadLibrary("Project2");
}
public static void main(String[] args) {
String argunment = "你好!";
callFile(argunment);
}
public native static void callFile(String path);
}
C源码:
#include"com_fmy_FMY.h"
JNIEXPORT void JNICALL Java_com_fmy_FMY_callFile
(JNIEnv * env, jclass jcl, jstring jsring){
char * JAVAchars=(*env)->GetStringUTFChars(env, jsring, NULL);
printf("在c中输出传入的字符串%s",JAVAchars);
}
输出 ��c�����������ַ���你好!
那么我们假设更换C或者java源文件的编码统一 为GB2312和UTF-8呢?
package com.fmy;
import java.io.UnsupportedEncodingException;
public class FMY {
static{
System.loadLibrary("Project2");
}
public static void main(String[] args) {
String argunment = "浣犲ソ!";
callFile(argunment);
}
public native static void callFile(String path);
}
发现源文件乱码
在c中输出传入的字符串娴g姴銈?!
发现传入的字符串又乱码了 ,”g姴銈?!”和”浣犲ソ!”完全不一样,是不是因为更换gbk后源文件乱码没修改?那么我们再试试
把java修改为GBK之后的乱码修改
package com.fmy;
import java.io.UnsupportedEncodingException;
public class FMY {
static{
System.loadLibrary("Project2");
}
public static void main(String[] args) {
String argunment = "你好";
callFile(argunment);
}
public native static void callFile(String path);
}
输出:
在c中输出传入的字符串浣犲ソ
依然乱码
解决思路:
(*env)->GetStringUTFChars(env, jsring, NULL);
#include"com_fmy_FMY.h"
#include
char* Utf8ToGb2312(char *p);
JNIEXPORT void JNICALL Java_com_fmy_FMY_callFile
(JNIEnv * env, jclass jcl, jstring jsring){
char * cstr = (*env)->GetStringUTFChars(env, jsring, NULL);
printf("在c中输出传入的字符串%s", Utf8ToGb2312(cstr));
}
/*************************************************
*将GB2312编码的字符串转为UTF-8编码
*输入:
*p:指向待转码字符串
*返回:
*指向已转码字符串的指针
*过程:
*将GB2312转为Unicode编码
*再将Unicode转为UTF-8
*************************************************/
char* Gb2312ToUtf8(char *p){
DWORD dwNum = MultiByteToWideChar(CP_ACP, 0, p, -1, NULL, 0);
char *psText;
wchar_t *pwText = (wchar_t*)malloc(dwNum*sizeof(wchar_t));
dwNum = MultiByteToWideChar(CP_ACP, 0, p, -1, pwText, dwNum);
dwNum = WideCharToMultiByte(CP_UTF8, 0, pwText, -1, NULL, 0, NULL, NULL);
psText = (char*)malloc(dwNum*sizeof(char));
dwNum = WideCharToMultiByte(CP_UTF8, 0, pwText, -1, psText, dwNum, NULL, NULL);
free(pwText);
return psText;
}
/*************************************************
*将UTF-8编码的字符串转为GB2312编码
*输入:
*p:指向待转码字符串
*返回:
*指向已转码字符串的指针
*过程:
*将UTF-8转为Unicode编码
*再将Unicode转为GB2312
*************************************************/
char* Utf8ToGb2312(char *p){
DWORD dwNum = MultiByteToWideChar(CP_UTF8, 0, p, -1, NULL, 0);
char *psText;
wchar_t *pwText = (wchar_t*)malloc(dwNum*sizeof(wchar_t));
dwNum = MultiByteToWideChar(CP_UTF8, 0, p, -1, pwText, dwNum);
dwNum = WideCharToMultiByte(CP_ACP, 0, pwText, -1, NULL, 0, NULL, NULL);
psText = (char*)malloc(dwNum*sizeof(char));
dwNum = WideCharToMultiByte(CP_ACP, 0, pwText, -1, psText, dwNum, NULL, NULL);
free(pwText);
return psText;
}
linux下可以用链接中的函数库
输出:在c中输出传入的字符串你好
tip:把c源文件改为UTF-8也可以哦,解决步骤和上面差不多
现在 c文件是默认的GB2312 ,java是UTF-8
java源码:
package com.fmy;
import java.io.UnsupportedEncodingException;
public class FMY {
static{
System.loadLibrary("Project2");
}
public static void main(String[] args) {
String fromC = callFile();
System.out.println(fromC);
}
public native static String callFile();
}
c函数实现:
JNIEXPORT jstring JNICALL Java_com_fmy_FMY_callFile
(JNIEnv * env, jclass jcl){
return (*env)->NewStringUTF(env,"嘿嘿是的!!!");
}
输出:ºٺÙÊǵÄ!!
解决办法:
把c源文件保存为UTF-8 不带签名类型的文件
输出:嘿嘿是的!!!
tip:当然你也可以试试吧java换gbk
解决办法2:
由于在c中写字符串是GB2312那么用string的构造方法构造出gb2312格式即可完成
JNIEXPORT jstring JNICALL Java_com_fmy_FMY_callFile
(JNIEnv * env, jclass jcs){
char *cstr = "我说中文?";
//String类的jclass
jclass str_cls = (*env)->FindClass(env, "java/lang/String");
jmethodID constructor_mid = (*env)->GetMethodID(env, str_cls, "" , "([BLjava/lang/String;)V");
//char * -> char[] ->jbyteArray -> jbyte *
jbyteArray bytes = (*env)->NewByteArray(env, strlen(cstr));
//bytes数组赋值
(*env)->SetByteArrayRegion(env, bytes, 0, strlen(cstr), cstr);
jstring charsetName = (*env)->NewStringUTF(env, "gb2312");
//
return (*env)->NewObject(env, str_cls, constructor_mid, bytes, charsetName);
}
输出:嘿嘿!!!!