`
bjmike
  • 浏览: 283113 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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);否则程序会阻塞。

分享到:
评论

相关推荐

    使用C++创建java虚拟机JVM,使用JNI调用java函数.zip

    在提供的资源"使用C++创建java虚拟机JVM,使用JNI调用java函数"中,可能详细介绍了以上步骤的实际应用,包括代码示例和可能遇到的问题及解决方案。通过学习和实践这个教程,开发者可以更好地理解和掌握C++与Java之间...

    visual studio 2019下C++通过JNI调用JAVA代码

    在本文中,我们将深入探讨如何在Visual Studio 2019环境下使用C++通过Java Native Interface (JNI)来调用Java代码。JNI是Java平台的一部分,它为Java应用程序提供了与本地代码交互的能力,使得开发者可以将Java应用...

    在Qt平台C++和Java代码的交互

    同样,C++也可以通过JNI调用Java的方法。 在Qt中,可以使用QProcess或其他I/O组件来启动JVM并传递参数,以执行Java代码。同时,可以使用信号和槽机制来协调C++和Java之间的事件处理。 为了在实际项目中实现这一...

    C++调用java jar包测试代码

    在C++中调用Java代码,一般会用到JNI(Java Native Interface),它提供了一种方式让Java代码可以调用本地(Native)代码,反之亦然。 - JNI定义了一套函数,使得C/C++可以创建Java对象,调用Java方法,处理异常等...

    Android-JNI完整工程,实现c++调用java和java调用c++

    - 通过`JNIEnv`指针,C++可以查找并调用Java对象的方法,访问字段,甚至创建新的Java对象。 8. **构建流程**: - 使用NDK(Native Development Kit)编译C/C++代码,生成.so文件。 - 将.so文件放置在项目的`jni...

    visual studio 2019下C++通过JNI调用JAVA代码.rar

    本教程将详细讲解如何在Visual Studio 2019环境下,利用C++通过Java Native Interface (JNI) 调用Java代码。首先,我们需要了解JNI的概念和作用。 JNI是Java平台提供的一种接口,允许Java代码和其他语言写的代码...

    C++调用java方式

    首先,C++调用Java主要依赖于Java Native Interface(JNI),这是Java平台标准的一部分,允许Java代码和其他语言写的代码进行交互。JNI为C/C++提供了接口,使得它们可以调用Java的方法,反之亦然。 **JNI基本概念**...

    实战-C++调用Java函数

    JNI是Java提供的一种机制,使得本地(Native)代码(如C++)能够与Java虚拟机(JVM)通信,调用Java类和方法。 在压缩包中的文件列表中,我们看到: 1. `FunCall_C2Java_Callee.jar` - 这是一个Java编译后的可执行...

    易语言JAVA调用 例子

    易语言与Java的交互通常依赖于Java本地接口(JNI),这是一种让Java代码调用本地(如C、C++或易语言)代码,反之亦然的机制。JNI提供了一套接口,允许Java代码生成特定平台的原生代码,这样就可以直接与操作系统或...

    C++调用Java参考代码

    它也允许C++代码调用Java对象的方法,访问和修改Java对象的字段,以及处理Java数组。 二、C++调用Java的步骤 1. **编写Java类**:首先,你需要一个包含要被C++调用的Java方法的类。这个类通常会包含一个`native`...

    在C或C++中调用JAVA方法

    在C或C++中调用JAVA方法是一种常见的跨语言交互技术,主要依赖于Java Native Interface (JNI)。JNI是Java平台的一部分,它允许Java代码和其他语言编写的代码进行交互,从而实现混合编程。JNI提供了丰富的API,使得...

    Delphi调用Java类和包源代码

    JNI允许Java代码调用本地(如C/C++或Delphi)代码,反之亦然。 1. **安装Java JDK**:首先,确保你已经在你的系统上安装了Java Development Kit (JDK),因为Delphi需要与JVM进行交互,而JDK包含了必要的头文件和库...

    C++库封装JNI接口-实现java调用c++

    Java Native Interface (JNI) 是Java平台提供的一种机制,允许Java代码和其他语言写的代码进行交互。本教程将详细讲解如何将C++库封装为JNI接口,以便于Java程序调用。 首先,了解JNI的基本概念。JNI是一套接口,它...

    c++调用jar包

    这将定义C/C++函数原型,这些函数将在C++代码中实现,用于调用Java方法。 2. **编写C++代码**:在生成的头文件中,你可以看到Java方法的本地接口。在C++源文件(如`Interface.cpp`和`MyFunction.cpp`)中实现这些...

    在 C/C++ 中调用 Java

    在C/C++中调用Java代码,主要依赖于Java Native Interface (JNI),这是一个允许Java代码与本地代码交互的标准接口。JNI使得开发者可以将C/C++的高性能代码集成到Java应用程序中,或者从C/C++程序中调用Java的类和...

    java调用c++生成so库

    这时,我们可以使用Java Native Interface (JNI) 来实现Java代码与C++代码的交互。JNI允许Java应用程序调用或者被C/C++代码调用,形成了跨语言的桥梁。 标题“java调用c++生成so库”指的是在Linux环境下,通过JNI...

    JNI技术手册 c/c++调用java

    **JNI(Java Native Interface)** 是Java平台的一部分,它允许Java代码与其他语言写的代码进行交互,尤其是C和C++。JNI是Java与本地代码之间沟通的桥梁,使得Java应用程序能够调用本地库中的方法,同时也支持从本地...

    c++和java互调代码示例

    - 导入库:C++代码需要链接到libjvm.so库(在Unix-like系统上)或jvm.dll(在Windows上)来访问Java虚拟机(JVM)的内部功能。 - Java类和方法ID:JNI提供函数来获取Java类的实例和方法ID,这是调用Java方法的关键...

    JNI调用C++代码和C++层回调java层 demo

    在Java代码中,我们可以添加一个`sayHelloFromJava`方法,以便在C++回调时调用: ```java public class HelloJni { // ... public void sayHelloFromJava() { System.out.println("Hello from Java!"); } ...

    jni.zip_C++ JNI_JNI 调用java_c调用java_jni_jni jdk1

    在Java应用程序中,JNI允许Java代码与用C、C++等本地语言编写的代码进行交互,实现了Java虚拟机(JVM)与本地代码的无缝连接。JNI在各种场景下都有广泛应用,例如性能优化、利用现有库、硬件访问等。 在这个“jni....

Global site tag (gtag.js) - Google Analytics