JNIjw04
1、VC6(CPP)的DLL代码:
#include<stdio.h> #include "jniZ_JNIjw04.h" #include <string> #include <algorithm> using namespace std; JNIEXPORT void JNICALL Java_jniZ_JNIjw04_CallCppFunction (JNIEnv * env, jobject obj) { printf("Java_jniZ_JNIjw04_CallCppFunction - 1\n"); // 获取obj中对象的class对象 jclass clazz = env->GetObjectClass(obj); // 获取java中的属性:msg jfieldID fid_msg = env->GetFieldID(clazz, "msg", "Ljava/lang/String;"); // 获取属性msg的对象 jstring j_msg = (jstring)env->GetObjectField(obj, fid_msg); jsize iLen = env->GetStringUTFLength(j_msg); // ZC: 添加byZC // 第一种方式 START // 获取字符串指针 const jchar * jstr01 = env->GetStringChars(j_msg, NULL); // 转换成宽字符串 //wstring wstr01((const wchar_t *)jstr01); // ZC: 尾部 非L'\0'问题 wstring wstr01((const wchar_t *)jstr01, iLen); // ZC: 从打印的信息可以看到 wstring的此种构造函数是拷贝字符串,并非直接使用字符串指针 printf("01 ==> %d , %S , %S , 0x%08X, 0x%08X\n", iLen, jstr01, wstr01.c_str(), jstr01, wstr01.c_str()); // 释放指针 env->ReleaseStringChars(j_msg, jstr01); // 第一种方式 STOP // 第二种方式 START // 获取字符串指针 const jchar * jstr02 = env->GetStringCritical(j_msg, NULL); // 转换成宽字符串 //wstring wstr02((const wchar_t *)jstr02); // ZC: 尾部 非L'\0'问题 wstring wstr02((const wchar_t *)jstr02, iLen); printf("02 ==> %d , %S , %S , 0x%08X, 0x%08X\n", iLen, jstr02, wstr02.c_str(), jstr02, wstr02.c_str()); // 释放指针 env->ReleaseStringCritical(j_msg, jstr02); // 第二种方式 STOP // 第三种方式 START // 获取字符串的长度 jsize len = env->GetStringLength(j_msg); // 生成长度为len的字符串指针 jchar *jstr = new jchar[len+1]; // C++中字符串以'\0'结尾,不然会输出意想不到的字符 jstr[len] = L'\0'; // ZC: 注意这里是 宽字符 // 将字符串 j_msg复制到jstr中 env->GetStringRegion(j_msg, 0, len, jstr); // 转换成宽字符串 wstring wstr((const wchar_t*)jstr); // 释放指针 delete[] jstr; // 第三种方式 STOP // 将字符串进行倒序 reverse(wstr.begin(), wstr.end()); // 获取倒序后的新的字符串 jstring j_new_str = env->NewString((const jchar*)wstr.c_str(), (jint)wstr.size()); // 将新的字符串设置到变量中 env->SetObjectField(obj, fid_msg, j_new_str); printf("Java_jniZ_JNIjw04_CallCppFunction - 2\n"); }
2、Java代码:
package jniZ; import java.io.BufferedReader; import java.io.InputStreamReader; public class JNIjw04 { //定义一个本地方法 public native void CallCppFunction(); //定义一个String属性 public String msg = null; public static void main(String[] args)throws Exception { //调用动态链接库 System.loadLibrary("JNIjwVC6_04"); //从控制台中获取值 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String str = reader.readLine(); JNIjw04 jni04 = new JNIjw04(); jni04.msg = str; jni04.CallCppFunction(); System.out.println(jni04.msg); } }
3、Java控制台输出:
ZC: 控制台信息中,第1行 是我的输入信息。"02 ==> "开头的这一行信息中,可以看到 返回的Unicode字符串 尾部非L'\0'问题(这一行信息中 字符串里面有一个乱码字符,然后后面才是L'\0')。
4、
5、