zoukankan      html  css  js  c++  java
  • java调用c++ dll出现中文乱码

    近期的开发用到了使用java调用本机动态连接库的功能,将文件路径通过java调用C++代码对文件进行操作。

    在调用中假设路径中包括有中文字符就会出现故障。程序执行就会中止。

    以下用一个小样例,来说明记录下解决办法。

    java中传入一个字符串,调用c++代码将字符串输出

    public class CommonUtil
    {
    	static
    	{
    		System.loadLibrary("nativeTest");
    	}
    	public native static void Print(String str);
    	public static void main(String args[])
    	{
    		CommonUtil.Print("中文乱码");
    	}
    }

    运行javac CommonUtil.java和javah CommonUtil两条命令。会生成一个CommonUtil.h的c++头文件。CommonUtil.h的源代码例如以下

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class CommonUtil */
    
    #ifndef _Included_CommonUtil
    #define _Included_CommonUtil
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     CommonUtil
     * Method:    Print
     * Signature: (Ljava/lang/String;)V
     */
    JNIEXPORT void JNICALL Java_CommonUtil_Print
      (JNIEnv *, jclass, jstring);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    使用vs2005新建一个c++ dll的project。将CommonUtil.h增加到项目中。再新建一个.cpp文件,用于实现Java_CommonUtil_Print这个函数。实现代码例如以下:

    #include "CommonUtil.h"
    #include <iostream>
    using namespace std;
    
    JNIEXPORT void JNICALL Java_CommonUtil_Print
    			(JNIEnv *env, jclass obj, jstring jStr)
    {
    	const char *localStr = env->GetStringUTFChars(jStr,NULL);
    	cout<<localStr<<endl;
    }
    在编译中须要增加java自带的c++头文件,否则比方像JNIEnv这种类就会找不到,我用的是jdk1.6,所以了"C:Program FilesJavajdk1.6.0_10include;C:Program FilesJavajdk1.6.0_10includewin32"到项目属性中。


    编译后生成一个dll。将dll拷到刚才编译的.class所在的目录中(做为一个简单的測试,没有使用包。假设使用包情况会略有不同)。

    运行命令java CommonUtil输出例如以下


    如今还全然搞清楚出现乱码的情况,只是网上有将java的utf编码转换成gb2312的代码。

    以下是转换的代码,代码来源:http://blog.csdn.net/yiyaaixuexi/article/details/6173592

    char* jstringToWindows( JNIEnv *env, jstring jstr )
    { //UTF8/16转换成gb2312
      int length = (env)->GetStringLength(jstr );
      const jchar* jcstr = (env)->GetStringChars(jstr, 0 );
      char* rtn = (char*)malloc( length*2+1 );
      int size = 0;
      size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL );
      if( size <= 0 )
        return NULL;
      (env)->ReleaseStringChars(jstr, jcstr );
      rtn[size] = 0;
      return rtn;
    }
    将Java_CommonUtil_Print改成例如以下:

    JNIEXPORT void JNICALL Java_CommonUtil_Print
    			(JNIEnv *env, jclass obj, jstring jStr)
    {
    	char *localStr = jstringToWindows(env, jStr);
    	cout<<localStr<<endl;
    	free(localStr);
    }
    又一次编译,生成后的dll再拷到.class所在的目录中。

    运行java CommonUtil


    执行正常


  • 相关阅读:
    webservice的几种调用方式
    捕获的异常到控制台的的信息转为String输出,在保存日志方面有用
    IO文件的读取与写入
    eclipse修改内存大小
    Oracle序列的创建与删除
    NFS挂载-实现文件共享
    arraylList.add(int,obj)的底层是怎么样的??
    Oracle修改表字段数据类型
    SVN版本库打包迁移备份恢复
    linux中tar详解
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/7092571.html
Copyright © 2011-2022 走看看