C++ 访问JVM调用java代码

C++ 访问JVM调用java代码

主程序有C++启动,C++调用java接收字符串,然后c++ 对接收到的字符串进行分词,分词后的结果再返回给java程序。
C++代码
// Defines the entry point for the console application.
//

#include <stdlib.h>
#include <iostream>
#include <jni.h>

#include "Xml4nlp.h"
#include "Ltp.h"

using namespace std;

static XML4NLP xml4nlp;
static LTP ltp(xml4nlp);

string parse(string sentence) {

ofstream log_file("test.log");
cout << "Input sentence is: " << sentence << endl;
xml4nlp.CreateDOMFromString(sentence);
ltp.crfWordSeg();
ltp.postag();
ltp.ner();
ltp.gparser();
ltp.srl();
int wordNum = xml4nlp.CountWordInDocument();
for (int i = 0; i < wordNum; ++i) {
const char* word = xml4nlp.GetWord(i);
if (word != NULL) {
log_file << word << " ";
}
}

string result;
xml4nlp.SaveDOM(result);
cout << "Result is: " << result << endl;
xml4nlp.ClearDOM();
return result;
}

jstring str2jstring(JNIEnv* env, const char* pat) {
//定义java String类 strClass
jclass strClass = (env)->FindClass("Ljava/lang/String;");
//获取String(byte[],String)的构造器,用于将本地byte[]数组转换为一个新String
jmethodID ctorID = (env)->GetMethodID(strClass, "<init>",
"([BLjava/lang/String;)V");
//建立byte数组
jbyteArray bytes = (env)->NewByteArray(strlen(pat));
//将char* 转换为byte数组
(env)->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*) pat);
// 设置String, 保存语言类型,用于byte数组转换至String时的参数
jstring encoding = (env)->NewStringUTF("GB2312");
//将byte数组转换为java String,并输出
return (jstring) (env)->NewObject(strClass, ctorID, bytes, encoding);
}

std::string jstring2str(JNIEnv* env, jstring jstr) {
char* rtn = NULL;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("GB2312");
jmethodID mid = env->GetMethodID(clsstring, "getBytes",
"(Ljava/lang/String;)[B");
jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
jsize alen = env->GetArrayLength(barr);
jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
if (alen > 0) {
rtn = (char*) malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
env->ReleaseByteArrayElements(barr, ba, 0);
std::string stemp(rtn);
free(rtn);
return stemp;
}

string receive(jmethodID mid,JNIEnv *env, jclass cls) {
string ret;

if (mid != 0) {
jstring read = (jstring) env->CallStaticObjectMethod(cls, mid);
//printf("Result of read: %s\n", read);
string read1 = jstring2str(env, read);
ret = parse(read1);
}
return ret;
}

void send(jmethodID mid,JNIEnv *env, jclass cls,string ret) {

if (mid != 0) {
const char* pat=ret.c_str();
jstring arg = str2jstring(env, pat);
env->CallStaticObjectMethod(cls, mid, arg);
//env->ReleaseStringUTFChars(arg, pat);
}
}

int main(int argc, char *argv[]) {

cout << "Begin ..." << endl;
JavaVMOption options[1];
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
long status;
jclass cls;
jmethodID mid;
jint square;
jboolean not1;
jstring read;

options[0].optionString = (char *) "-Djava.class.path=./classes/activemq-all-5.7.0.jar:./classes";
memset(&vm_args, 0, sizeof(vm_args));
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 1;
vm_args.options = options;
status = JNI_CreateJavaVM(&jvm, (void**) &env, &vm_args);

if (status != JNI_ERR) {
cls = env->FindClass("Server");
if (cls != 0) {
mid = env->GetStaticMethodID(cls, "await", "()V");
if (mid != 0) {
env->CallStaticObjectMethod(cls, mid);
printf("await ok \n");
}

jmethodID rmid = env->GetStaticMethodID(cls, "readReceive",
"()Ljava/lang/String;");


jmethodID smid = env->GetStaticMethodID(cls, "putRet",
"(Ljava/lang/String;)V");

for (;;) {
string ret = receive(rmid,env, cls);
send(smid,env,cls,ret);
}

} else {
printf("cls==0 \n");
}

jvm->DestroyJavaVM();
return 0;
} else {
printf("JNI_ERR,%d", status);
return -1;
}
}


需要注意的是GetStaticMethodID 第二个参数是方法签名,可以通过jps -s ClassName获取。


Java代码
//package com.datou.analysis.service.cosinecluster;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
* Created with IntelliJ IDEA.
* User: lixiaoming@qmadou.com
* Date: 13-4-17
* Time: 下午2:06
* To change this template use File | Settings | File Templates.
*/
public class Server {

static BlockingQueue<String> queue = new ArrayBlockingQueue<String>(10240);
static AdapterMQMsgSnder snder = null;
public static void await() {
MessageService messageService = new MessageService();
messageService.setUrl("tcp://localhost:61616");
messageService.setUser("admin");
messageService.setPassword("datuu_datuu");

snder = new AdapterMQMsgSnder();
snder.setQname("MSG_RES");
snder.setMessageService(messageService);

final MQMsgRcver rcver = new MQMsgRcver();
rcver.setQname("MSG_REQ");
rcver.setService(messageService);

Thread tt = new Thread(){
public void run(){
for(;;){
try {
System.out.println("rcvMsgQ begin");
String resMsgEntity = rcver.rcvMsgQ();
if (resMsgEntity != null) {
queue.put(resMsgEntity);
System.out.println("get reslt_ok");
}
System.out.println("rcvMsgQ end");
} catch (Exception e) {
e.printStackTrace();
rcver.closeConnection();
Util.sleepSecs(3);
}
}
}
} ;
tt.setDaemon(true);
tt.start();
}

public static String readReceive(){
String ss = null;
try {
ss = queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
return ss;
}

public static void putRet(String ret){
System.out.println("putRet ["+ret+"]");
snder.sendMsgQ(ret);
}

}



注意 java中使用线程时候,一定要tt.setDaemon(true);否则程序会阻塞。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值