C++ 调用Java 类库

最近一段时间重拾C++开发,做了几年的javascript开发后,在回到C++开发中,确实感觉C++的开发效率以及便利性方面不是很好,不知道像C、C++这些语言以后还能不能重回霸主地位。

C++中某些类库不太健全,java正好有响应的类库,简单的做法就是C++通过JNI调用java类库了。

1、搭建java环境

很多年以前学过一点java知识,现在已经不记得了,甚至配置java的开发环境都不知道了,搭建java环境需要安装jdk,jdk中包含了java的类库、字节码运行环境jvm、与C++相互调用的接口(如JNI)、jre(java运行环境就在jre中)。

下载官网的jdk,官网的jdk版本已经到了17版本了,网上的教程大多使用的是1.8的版本,我已使用的是1.8,下载后安装完成后需要配置jdk的环境变量,比如JAVA_HOME、CLASSPATH、PATH等。

下载eclipse,傻瓜式安装就可以了。

2、编写java的例程

package test;
public class Demo   
{
	public String append(String str, int i)  
	{  
		return str + i;  
	}  
	
	public int add(int a, int b)  
	{  
		return a + b;  
	}
}

编写例子的时候犯了几个错误,首先package这个关键字是Demo.java编译出来存放的目录,就因为这个目录导致我在写C++的时候一直调用不成功。

3、编译java程序

使用java命令行工具:"javac D:\\Demo.java"后会在我的盘符下创建一个Demo.class文件,将这个文件放到"D:\test\Demo.class"目录下才是正确的目录

4、方法签名

C++调用java的方式是通过方法签名的方式调用的,形如:

    //查找test.Demo类,返回JAVA类的CLASS对象  
    jclass cls = env->FindClass("test/Demo");  
    //根据类的CLASS对象获取该类的实例  
    jobject obj = env->AllocObject(cls);  
      
    //获取类中的方法,最后一个参数是方法的签名,通过javap -s -p 文件名可以获得  
    jmethodID mid = env->GetMethodID(cls, "add","(II)I");  
    //构造参数并调用对象的方法  
    const char szTest[] = "123";  

GetMethodID(cls, "add","(II)I");是用来获取类似函数指针的东西,需要三个参数:类的名称、函数名称、方法签名。

方法签名的获取方式是通过javap这个命令“javap -s -p c:\ test\Demo.class”

D:\>javap -s -p D:\test\Demo.class
Compiled from "Demo.java"
public class test.Demo {
  public test.Demo();
    descriptor: ()V

  public java.lang.String append(java.lang.String, int);
    descriptor: (Ljava/lang/String;I)Ljava/lang/String;

  public int add(int, int);
    descriptor: (II)I
}

4、C++调用

#include "windows.h"  
#include <jni.h>
#include <string>  
#include <iostream>  
using namespace std;  
  
jstring NewJString(JNIEnv *env, std::string str);  
  
int main()  
{  
    //定义一个函数指针,下面用来指向JVM中的JNI_CreateJavaVM函数  
    typedef jint (WINAPI *PFunCreateJavaVM)(JavaVM **, void **, JavaVMInitArgs *);  
      
    int res;  
    JavaVMInitArgs vm_args;  
    JavaVMOption options[3];  
    JavaVM *jvm;  
    JNIEnv *env;  
      
    /*设置初始化参数*/  
    //disable JIT,这是JNI文档中的解释,具体意义不是很清楚 ,能取哪些值也不清楚。  
    //从JNI文档里给的示例代码中搬过来的  
    options[0].optionString = const_cast<char*>("-Djava.compiler=NONE");  
    //设置classpath,如果程序用到了第三方的JAR包,也可以在这里面包含进来  
    options[1].optionString = const_cast<char*>("-Djava.class.path=.;D:\\");  
    //设置显示消息的类型,取值有gc、class和jni,如果一次取多个的话值之间用逗号格开,如-verbose:gc,class  
    //该参数可以用来观察C++调用JAVA的过程,设置该参数后,程序会在标准输出设备上打印调用的相关信息  
    options[2].optionString = const_cast<char*>("-verbose:NONE");  
          
    //设置版本号,版本号有JNI_VERSION_1_1,JNI_VERSION_1_2和JNI_VERSION_1_4  
    //选择一个根你安装的JRE版本最近的版本号即可,不过你的JRE版本一定要等于或者高于指定的版本号  
    vm_args.version = JNI_VERSION_1_8;  
    vm_args.nOptions = 3;  
    vm_args.options = options;  
    //该参数指定是否忽略非标准的参数,如果填JNI_FLASE,当遇到非标准参数时,JNI_CreateJavaVM会返回JNI_ERR  
    vm_args.ignoreUnrecognized = JNI_TRUE;  
    //加载JVM.DLL动态库  
    HINSTANCE hInstance = ::LoadLibrary(L"../x64/Debug/jre/bin/server/jvm.dll");
    if (hInstance == NULL)  
    {  
        return false;  
    }  
    //取得里面的JNI_CreateJavaVM函数指针  
    PFunCreateJavaVM funCreateJavaVM = (PFunCreateJavaVM)::GetProcAddress(hInstance, "JNI_CreateJavaVM");  
    //调用JNI_CreateJavaVM创建虚拟机  
    res = (*funCreateJavaVM)(&jvm, (void**)&env, &vm_args);  
    if (res < 0)  
    {  
        return -1;  
    }  
    //查找test.Demo类,返回JAVA类的CLASS对象  
    jclass cls = env->FindClass("test/Demo");  
    //根据类的CLASS对象获取该类的实例  
    jobject obj = env->AllocObject(cls);  
      
    //获取类中的方法,最后一个参数是方法的签名,通过javap -s -p 文件名可以获得  
    jmethodID mid = env->GetMethodID(cls, "add","(II)I");  
    //构造参数并调用对象的方法  

    int result = (int) env->CallObjectMethod(obj, mid, 11, 12); 
    cout<<result;    
    //销毁虚拟机并释放动态库  
    jvm->DestroyJavaVM();  
    ::FreeLibrary(hInstance);  
    return 0;  
}  
  

可以参考 C++调用JAVA方法详解_c_z_w的博客-CSDN博客_c++调用java方法  的过程

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 是的,Delphi可以调用Java接口。 Delphi是一种编程语言和集成开发环境,主要用于Windows平台的应用程序开发。Java是一种面向对象的编程语言,广泛用于开发跨平台的企业级应用程序。 Java接口是一种定义了一组方法的抽象类型,用于实现类之间的约定。通过接口,我们可以实现类的多态性和代码的复用。 在Delphi中,我们可以使用JNI(Java Native Interface)来调用Java接口。JNI允许我们在Delphi应用程序中使用Java类和接口,通过这种方式,我们可以与Java平台进行交互。 要调用Java接口,我们首先需要将Java代码编译为Java类文件,并使用Java编译器生成带有C风格函数原型的动态链接库(DLL)。 然后,在Delphi中,我们使用LoadLibrary函数加载DLL,并使用GetProcAddress函数获取Java接口中的函数的地址。 接下来,我们可以使用JVM创建Java虚拟机,并通过调用接口方法来实现与Java交互。需要注意的是,我们需要将接口方法的参数和返回值类型转换为Delphi相应的类型。 在调用Java接口时,我们可以传递参数,并获取方法的返回值。通过这种方式,我们可以利用Delphi的强大功能和Java的跨平台优势进行开发。 总结而言,Delphi可以调用Java接口,通过JNI实现与Java的交互。这种跨平台的互操作性为开发者提供了更加灵活和强大的开发选择。 ### 回答2: Delphi是一种基于Object Pascal语言的集成开发环境(IDE),主要用于Windows平台上的应用程序开发。它提供了广泛的库和工具,可以快速开发各种类型的应用程序。 虽然Delphi和Java是两种不同的编程语言,但Delphi可以通过使用Java Native Interface(JNI)来调用Java接口。JNI是一种允许不同编程语言互相调用的机制,它提供了Java和其他编程语言之间的桥梁。 在Delphi中调用Java接口可以通过以下几个步骤完成: 1. 编写Java接口:首先,在Java中编写一个接口,定义要在Delphi中调用的方法和参数。 2. 使用Java编译器:将编写的Java接口编译成字节码文件(.class文件)。 3. 使用Delphi的JNI支持:在Delphi的代码中,使用JNI支持库(如Jvcl或JVCL)来加载Java的字节码文件,并将其转换为Delphi可以调用的方式。 4. 调用Java接口方法:一旦Java接口被加载,就可以在Delphi中使用其方法来调用Java代码。 通过这种方式,Delphi可以与Java进行交互,调用Java接口中定义的方法,并传递参数。这对于需要在Delphi应用程序中使用Java库或与其他Java应用程序进行通信的开发人员来说非常有用。 总结起来,Delphi可以通过JNI机制来调用Java接口,从而实现与Java的交互和通信。这为开发人员提供了更广泛的工具和库选择,加快了应用程序的开发速度和灵活性。 ### 回答3: 是的,Delphi可以通过使用Java Native Interface (JNI) 来调用Java接口。JNI 是Java平台提供的一种机制,它允许Java代码和非Java代码(如C++或Delphi)进行交互。 要在Delphi中调用Java接口,需要进行以下步骤: 1. 创建一个Java类,并在其中定义接口方法。 2. 使用Java编译器将该类编译为一个.jar文件。 3. 在Delphi中导入Java类库,可以使用Java Importer工具或JNI API进行导入。 4. 建立连接和协议,使Delphi能够调用Java方法。可以使用JNI API提供的函数来创建并连接到Java虚拟机(JVM)。 5. 在Delphi中编写代码,调用Java接口方法。 6. 运行Delphi应用程序,即可实现调用Java接口。 通过这种方式,Delphi程序可以利用Java所提供的各种功能和接口,而无需重新编写Java代码。这样可以提高开发效率和软件的复用性。 注意,为了确保调用的正确性和可靠性,必须仔细处理数据类型转换和参数传递等问题。 总之,Delphi通过JNI可以调用Java接口,并且可以从Java程序中获得所需的功能和特性。这使得Delphi开发人员能够利用Java丰富的生态系统,扩展和增强他们的应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值