使用JNI进行Java与C/C++语言混合编程

7 篇文章 0 订阅

C++调java

编写Java代码并编译

这段代码非常简单, 有个静态方法和成员方法, 一个public的成员变量

public class Sample2 {
    public String name;

    public static String sayHello(String name) {
        return "Hello, " + name + "!";
    }

    public String sayHello() {
        return "Hello, " + name + "!";
    }
}

 由于没有定义构造函数, 所以会有一个默认的构造函数.

运行下面的命令编译

javap -s -private Sample2

得到结果:

编写C++代码

#include <iostream>
#include <JavaVM/jni.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>


// 环境变量PATH在windows下和linux下的分割符定义
#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else
#define PATH_SEPARATOR ':'
#endif
using namespace std;
int main(int argc, const char * argv[]) {
  
    JavaVMOption options[1];
    JNIEnv *env= NULL;
    JavaVM *jvm= NULL;
    JavaVMInitArgs vm_args;
    
    
    jfieldID fid;
    jobject obj;
    
    options[0].optionString = "-Djava.class.path=/Users/yulei/work/C++/C++ Point/c++-java混编";
    memset(&vm_args, 0, sizeof(vm_args));
    vm_args.version = JNI_VERSION_1_4;
    vm_args.nOptions = 1;
    vm_args.options = options;

    // 启动虚拟机
    long status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    
    if (status != JNI_ERR)
    {
        // 先获得class对象
        jclass cls = env->FindClass("WinFile");
        if ( cls == 0 ) {
            std::cout << "No such class WinFile !" << std::endl;
            jvm->DestroyJavaVM();
            return 1;
        }
        
        if (cls != 0)
        {
            
//            // 获取方法ID, 通过方法名和签名, 调用静态方法
            jmethodID mid = env->GetStaticMethodID( cls, "sayHello", "(Ljava/lang/String;)Ljava/lang/String;" );
            if ( mid == 0 ) {
                std::cout << "No such class Method sayHello !" << std::endl;
                jvm->DestroyJavaVM();
            }
            if (mid != 0)
            {
                const char* name = "World";
                jstring arg = (env)->NewStringUTF( name);
                jstring result = (jstring)(env)->CallStaticObjectMethod( cls, mid, arg);
                const char* str = (env)->GetStringUTFChars( result, 0);
                printf("Result of sayHello: %s\n", str);
                (env)->ReleaseStringUTFChars( result, 0);
            }

            /*** 新建一个对象 ***/
            // 调用默认构造函数
            //obj = (*env)->AllocObjdect(env, cls);

            // 调用指定的构造函数, 构造函数的名字叫做<init>
            mid = (env)->GetMethodID( cls, "<init>", "()V");
            obj = (env)->NewObject( cls, mid);
            if (obj == 0)
            {
                printf("Create object failed!\n");
            }
            /*** 新建一个对象 ***/

            // 获取属性ID, 通过属性名和签名
            fid = (env)->GetFieldID( cls, "name", "Ljava/lang/String;");
            if (fid != 0)
            {
                const char* name = "icejoywoo";
                jstring arg = (env)->NewStringUTF( name);
                (env)->SetObjectField( obj, fid, arg); // 修改属性
            }

            // 调用成员方法
            mid = (env)->GetMethodID( cls, "sayHello", "()Ljava/lang/String;");
            if (mid != 0)
            {
                jstring result = (jstring)(env)->CallObjectMethod( obj, mid);
                const char* str = (env)->GetStringUTFChars( result, 0);
                printf("Result of sayHello: %s\n", str);
                (env)->ReleaseStringUTFChars( result, 0);
            }
        }
        
        (jvm)->DestroyJavaVM();
        return 0;
    }
    else
    {
        printf("JVM Created failed!\n");
        return -1;
    }
    return 0;
}

编译运行:

这就是通过JNI实现的C++和java的混编完成了,注意FindClass的java对象路径否则找不到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值