疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

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


 

 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);

    }

    }