C++ 到 Java 再到 C++

1 篇文章 0 订阅

最近把公司项目的一个消息插件换成JAVA,要在C++层调用java,在java里面会有自身的回调,然后我想在这个回调里面调回到我的c++代码里面。
之前做过C++到C#之间的调用,拿一套语法很复杂诡异,我以为C++和JAVA之间的互相调用也很复杂,等我搞定之后,发现,简直方便快捷。
下面说一下步骤。
1,我用的是VS2010,安装了JDK1.8。
2,要写一个JAVA类,如下。

package test;

public class Test{

    static{
         System.loadLibrary("testJni"); //这里是导入库,这个库就是本地方法的实现库文件。
    }

    public static void main(){
        System.out.println(hello());  //这个方法是JAVA类的自身成员,里面调用了本地方法。

    }
    public static native String  hello();//这是申明本地方法,即在JNI环境下执行的代码。
}

3,
先用javac test.java(上面代码的源文件名称),这时候会生成test.class。这个class文件,到时候会在vs2010里面的工程用到。如果不知道函数签名,最好是用 javap -s -p test来看看函数的签名。
4,
用 javah -jni test 这个时候会生成一个 test_Test.h 的头文件,这个文件里面申明了本地方法,需要我们在库中去实现方法。如下

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class test_Test */

#ifndef _Included_test_Test
#define _Included_test_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     test_Test
 * Method:    hello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_test_Test_hello(JNIEnv *, jclass); //这就是本地代码在头文件中的申明

//extern "C" __declspec(dllexport) void helloC();
void helloC();

#ifdef __cplusplus
}
#endif
#endif

5,
用VS2010新建一个DLL工程,配置好JAVA的环境变量,导入JAVA依赖库。导入test_Test.h 到工程,并新建一个test_Test.cpp,然后CPP代码如下

#include "stdafx.h"
#include "test_Test.h"
JNIEXPORT  jstring JNICALL Java_test_Test_hello(JNIEnv * env, jclass obj, )
{
    int a = 0;
    a ++;
    return env->NewStringUTF("world");
}

然后编译之后,testJni.dll 和 testJni.lib,只需要DLL文件就可以。
6,
VS2010新建一个工程,导入JAVA的环境。下面解说一下C++中如何调用JAVA的类,

JavaVMInitArgs vm_Args;
    JavaVMOption options[3];
    JavaVM * jvm = NULL;
    JNIEnv * env = NULL;
    jmethodID mid = NULL;

    options[0].optionString = "-Djava.class.path=E:\\JAVA\\project"; //这个是你的JVM启动的时候,它去找类的时候的根目录。如果按着我写的测试,那么这个路径就要写成你生成的class的目录。还要说一点就是,我的JAVA代码中,是有个test包名的,所以这个路径要在包名那个级别的目录。
    options[1].optionString = "-Djava.compiler=NONE";
    options[2].optionString = "-verbose:NONE";

    vm_Args.version = JNI_VERSION_1_8;
    vm_Args.nOptions = 1;
    vm_Args.options = options;

    vm_Args.ignoreUnrecognized = JNI_TRUE;
    res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_Args); //启动JAVA虚拟机

    jclass clstest = env->FindClass("test/Test"); //在test这个包下面,找Test这个类,
    jmethodID mid  = env->GetStaticMethodID(clstest, "main", "()V"); //这是找这个类的静态方法,后面那个“()V” ,是方法的签名。
    env->CallStaticVoidMethod(cls, mid); //这里是调用。
    这时候你会在控制台看到“world”的打印输出

总结一下,其实,C#和C++交互,JAVA和C++交互大致相同。都需要一个中间层来做过渡。在本文中,那个DLL就是中间层,用来把C++和 java中的数据做交换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值