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、

 

posted @ 2016-04-26 16:34  JavaSkill  阅读(272)  评论(0编辑  收藏  举报