Java JNI 调用C++ API及中文编码问题

openkk 12年前

Java调用C++可以通过JNI声明native方法进行调用,主要步骤有:

1. 声明类及相关nativ方法,加载要调用的C++库

package bupt.cist.nlp.ner;    public class ChineseNER {   static{    System.loadLibrary("CIST_NER");   }   public ChineseNER(){   }   public native void say(String msg);   public native String process(String line);  }
2. 到源码目录下,通过命令javah -jni bupt.cist.nlp.ner.ChineseNER编译类 ,生成.h头文件
/* DO NOT EDIT THIS FILE - it is machine generated */  #include "jni.h"  /* Header for class bupt_cist_nlp_ner_ChineseNER */    #ifndef _Included_bupt_cist_nlp_ner_ChineseNER  #define _Included_bupt_cist_nlp_ner_ChineseNER  #ifdef __cplusplus  extern "C" {  #endif  /*   * Class:     bupt_cist_nlp_ner_ChineseNER   * Method:    say   * Signature: (Ljava/lang/String;)V   */  JNIEXPORT void JNICALL Java_bupt_cist_nlp_ner_ChineseNER_say    (JNIEnv *, jobject, jstring);    /*   * Class:     bupt_cist_nlp_ner_ChineseNER   * Method:    process   * Signature: (Ljava/lang/String;)Ljava/lang/String;   */  JNIEXPORT jstring JNICALL Java_bupt_cist_nlp_ner_ChineseNER_process    (JNIEnv *, jobject, jstring);    #ifdef __cplusplus  }  #endif  #endif

3. 新建CIST_NER的dll工程,加载.h头文件,编写cpp文件实现dll库

#include <iostream>  #include <string>  #include "bupt_cist_nlp_ner_ChineseNER.h"  #include "windows.h"    using namespace std;    char* jstringToWindows( JNIEnv *env, jstring jstr )    {      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;    }    jstring WindowsTojstring( JNIEnv *env, const char* str )    {      jstring rtn = 0;      int slen = strlen(str);      unsigned short* buffer = 0;      if( slen == 0 )        rtn = env->NewStringUTF(str);       else      {        int length = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str, slen, NULL, 0);        buffer = (unsigned short*)malloc(length*2 + 1);        if( MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length) >0)          rtn = env->NewString((jchar*)buffer, length);      }      if(buffer)      free(buffer);      return rtn;    }    char* U2G(const char* utf8)  {    int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);    wchar_t* wstr = new wchar_t[len+1];    memset(wstr, 0, len+1);    MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);    len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);    char* str = new char[len+1];    memset(str, 0, len+1);    WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);    if(wstr) delete[] wstr;    return str;  }  char* G2U(const char* gb2312)  {    int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);    wchar_t* wstr = new wchar_t[len+1];    memset(wstr, 0, len+1);    MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);    len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);    char* str = new char[len+1];    memset(str, 0, len+1);    WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);    if(wstr) delete[] wstr;    return str;  }  JNIEXPORT void JNICALL Java_bupt_cist_nlp_ner_ChineseNER_say(JNIEnv *env, jobject obj, jstring msg)  {   const char* pmsg = env->GetStringUTFChars(msg, NULL);   cout << pmsg << endl;  }  JNIEXPORT jstring JNICAL Java_bupt_cist_nlp_ner_ChineseNER_process(JNIEnv *env, jobject obj, jstring line)  {   const char* pmsg = jstringToWindows(env, line);    cout << pmsg << endl;   // process       return WindowsTojstring(env, res.c_str());  }
4. 编译生成dll库,放在java工程目录下即可调用

package cpp;    import bupt.cist.nlp.ner.*;  public class test {     /**    * @param args    */   public static void main(String[] args) {    // TODO Auto-generated method stub    ChineseNER a = new ChineseNER();    String line = "星期一中国北京";    System.out.println(line);    String b = a.process(line);    a.say(b);   }  }



参考资料:

http://hi.baidu.com/08wschen/blog/item/27a298fcc86f6c3b5c6008ca.html

http://www.vckbase.com/index.php/wv/1327

http://blog.csdn.net/qq675927952/article/details/7496035