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
#include
#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