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+];
// C++中字符串以'\0'结尾,不然会输出意想不到的字符
jstr[len] = L'\0'; // ZC: 注意这里是 宽字符
// 将字符串 j_msg复制到jstr中
env->GetStringRegion(j_msg, , 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、

JNIjw04的更多相关文章

随机推荐

  1. java反射——字段

    大家都知道反射技术在Java里面时非常重要的一个技术点,因为Java好多框架的编写都是基于反射的,别的不多说,spring框架里面的IOC就是基于反射实现.那么什么是反射呢?JAVA反射机制是在运行状 ...

  2. c++用vector创建二维数组

    1 vector二维数组的创建和初始化 std::vector <int> vec(10,90); //将10个一维动态数组初始为90std::vector<std::vector& ...

  3. Java 语言基础之数组常见操作

    对数组操作最基本的动作: 存和取 核心思想: 就是对角标的操作 数组常见操作: 1, 遍历 2, 获取最大值和最小值 3, 排序 4, 查找 5, 折半查找 // 1. 遍历 int[] arr = ...

  4. Set 接口常用子类及其特点

    Set 集合中元素不可重复,是无序的(存入和取出的顺序是不一样的), Set 接口中的方法和 Collection 接口一致. 常用子类: HashSet : 内部数据结构是哈希表, 是不同步的 Li ...

  5. 《深入理解Linux网络技术内幕》阅读笔记 --- 邻居子系统

    1.封包从L3至L2的传送过程如下所示: 本地主机的路由子系统选择L3目的地址(下一个跃点). 根据路由表,如果下一个跃点在同一个网络中,邻居层就把目的L3地址解析为跃点的L2地址.这个关联会被放入缓 ...

  6. Django框架--路由分配系统

    Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...

  7. 【我的Android进阶之旅】解决bug:You need to use a Theme.AppCompat theme (or descendant) with this activity.

    前言 今天用Android Studio 生成Activity的时候,默认继承AppCompatActivity ,而在AndroidManifest.xml我对该Activity设置了一个主题,然后 ...

  8. [今日干货]一个吸粉效果也不错的APP

    最近陌陌被封很厉害,今天给大家分享一个吸粉效果也不错的APP——悦跑圈,日吸几百粉没问题~ 1.首先下载APP悦跑圈,用手机号码注册. 2.改写资料和头像,最好用一个女性头像,真实点的,不是网图,增加 ...

  9. linux安装tree命令

    安装 yum install -y tree 使用,比如显示/root的2层树结构 tree -L 2 /root 效果 /root ├── \033 ├── code │   └── hellowo ...

  10. boost智能指针总结

    智能指针是一种具备指针类似行为的对象,当不在需要它的时候自动删除其引用的c++对象.直接点说就是自动析构C++对象. boost提供了6种智能指针,如下所示: scoped_ptr <boost ...