java c/cpp互相调用实例(姊妹篇之二)
----------c/cpp调用java
本文是
javaJNI调用c/cpp实例(姊妹篇之一)的续集c/cpp调用java。
计划第三篇写一个java安装程序实例(客户端无jre环境的安装包),以解决java程序(软件)安装不方便的问题,使java程序安装也傻瓜化。
直接进入正题:
完成本实例需要下列工具/环境:
1、java环境
2、c/cpp编辑器。windows下推荐用vs/vc++,我用的是vs2008。linux下gcc/g++
从 C/CPP 程序调用 Java 代码需要四个步骤 :
一 编写 Java 代码。
二 编译 Java 代码。
三 编写 C/C++ 代码。
四 运行本机 C/C++ 应用程序。
1、编写java代码
为了达到示范作用,java方法我用两个,一个是静态方法,一个是普通方法。
C2java.java
package com.testJni.testDemo;
public class C2java {
public C2java(){
super();
}
public static int add(int a,int b) {
return a+b;
}
public boolean judge(boolean bool) {
return !bool;
}
}
静态方法的好处是我不用实例化,直接可以调用方法。调用起来比较简单,不容易出错。
2、编译java代码
javac 命令。(略)
3、编写 C/C++ 代码
我想在c/cpp中直接生成一个exe然后窗口输出结果,所以我就建立一个exe工程。编辑器jni环境是上篇已经搭建好的,所以这里只需要少量配置就可以了。好了,我们先建立一个工程:
打开vs2008,新建一 win32 console App 工程
键入工程名字c2java,点击OK,出来窗口点击next,选取console app
点击完成。到这里先不忙编码实现,我们先把环境搭建好,右键工程属性,选取 linker -->input,在右边窗口添加依赖jvm.lib,这个lib的位置在你%JAVA_HOME%/lib 下。如果你的路径中同我一样包含空格(例如Program Files)记得用引号括起来。
打开stdafx.h文件添加
#include <iostream>
#include <jni.h>
#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else
#define PATH_SEPARATOR ':'
#endif
打开c2java.cpp,键入下面的代码
using namespace std;
int main()
{
JavaVMOption options[1];
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
long status;
jclass cls;
jmethodID mid;
jint square;
jboolean not;
jobject jobj;
options[0].optionString = "-Djava.class.path=.";
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("com/testJni/testDemo/C2java");
if(cls !=0)
{
mid = env->GetStaticMethodID( cls, "add", "(II)I");
if(mid !=0)
{
square = env->CallStaticIntMethod( cls, mid, 5,5);
std::cout << square << std::endl;
}
mid = env->GetMethodID(cls,"<init>","()V");
if(mid !=0)
{
jobj=env->NewObject(cls,mid);
std::cout << "init ok" << std::endl;
}
mid = env->GetMethodID( cls, "judge","(Z)Z");
if(mid !=0)
{
not = env->CallBooleanMethod(jobj, mid, 1);
if(!not){
std::cout << "Boolean ok" << std::endl;
}
}
}
jvm->DestroyJavaVM();
return 0;
}
else
return -1;
}
下面解释下上面的代码:
JavaVMOption options[] 具有用于 JVM 的各种选项设置。声明的 JavaVMOption options[] 数组足够大,就能容纳我们希望使用的所有选项。在本实例中,我们使用的选项就是类路径选项。
JNIEnv *env 表示 JNI 执行环境。
JavaVM *jvm 是指向 JVM 的指针。我们主要使用这个指针来创建、初始化和销毁 JVM。JavaVMInitArgs vm_args 表示可以用来初始化 JVM 的各种 JVM 参数。
设置参数后,创建我们的jvm :
status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
成功返回0,不成功返回JNI_ERR。
创建完成后,我们就可以查找我们的class了,因为我们的java类一般都有包,所以我们也要加上包路径com/testJni/testDemo/C2java
在这里我们会使用到java的一个命令javap ,这个命令有什么用那,我们用javap -s -p C2java看看
打开jni.h我们会发现,Signature就是sig,也就是GetStaticMethodID( cls, "add", "(II)I")方法的第三个参数。GetStaticMethodID表示调用static方法,GetMethodID调用普通方法。下面就是传入参数,打出结果。
在看jni.h的时候我们注意到有 CallStaticXXXMethod() 和 CallXXXMethod() 之类的方法。这些方法分别代表调用静态方法和成员方法,用方法的返回类型(例如,Object、Boolean、Byte、Char、Int、Long 等等)代替变量 XXX。
静态方法和普通方法不同之处就是普通方法必须要先实例化一个java对象,调用构造器的时候方法的名称为“<init>”。
下面的代码就不用我再解释了,先是new一个实例出来,然后调用实例的方法。
最后记得销毁jvm。
代码解释完了,我们build下这个工程,生成c2java.exe。
4、运行exe
因为我们生成的exe需要调用jvm.dll初始化,为了使运行的exe不报错误,我们把%JAVA_HOME%/jre/bin/server也加进path目录。方便系统自动搜索jvm.dll。
运行结果:
最后补充:本实例并没有涉及到java的异常、java c/cpp的编码转换问题,对于异常问题,C里没有异常,请使用jni的异常处理函数。编码转换问题上篇已有介绍,此处略去。
- 大小: 39.9 KB
- 大小: 25.2 KB
- 大小: 57.8 KB
- 大小: 21.7 KB
- 大小: 3.9 KB
分享到:
相关推荐
III. java c/cpp互相调用实例(姊妹篇之二)——c/cpp调用java 11 一、 编写java代码 12 二、 编译java代码 12 三、 编写 C/C++ 代码 13 四、 运行exe 18 IV. Java JNI 编程进阶 18 一、 解决性能问题 18 二、 解决...
JNI 调用 c pp互相调用实例, java JNI cpp互相调用实例
Android Java 如何调用自己的 C++ 的类库 下面以 Java 调用 C++ 的加法运算函数为例,做简单说明。 (使用 Android Studio 3 编译) 首先编译 c++ 类库 创建独立目录存放 c++ 文件,例如 “app/src/main/cpp/add.cpp...
实例1: 1)使用javah 生成.h文件 2)根据.h文件,编写.cpp源程序。 实例2: 1)演示了java调用c++,以及c++调用java。 2)java 与 c++ 间,通过复杂数据类型(Vector)作为参数来传递数据。
新来的一个工程师不懂HBase,java不熟,python还行,我建议他那可以考虑用HBase的thrift调用,完成目前的工作。 首先,安装thrift 下载thrift,这里,我用的是thrift-0.7.0-dev.tar.gz 这个版本 tar xzf thrift-...
注:在PowerManagerService 类中没有实现nativeAcquireWakeLock,其实现体在 frameworks/base/core/jni/android_os_Power.cpp中,所以nativeAcquireWakeLock()方法时会调用JNI下的实现方法。 3).JNI层的实现 ...
掷骰子游戏 这是我编写的所有三个版本的掷骰子游戏(Java、Java GUI 和 C++)的存储库。... 但是,GUI 程序要求 Game.java 和 Dice.java 文件位于同一项目文件夹中,因为 Game.java 在其方法中调用 Dice.java 的实例。
-> HAL 客户端(Camera.cpp)调用 connect 与服务端(CameraService.cpp)连接得到 CameraService 中的 CameraClient 的一个实例 ->服务端 CameraClient 的初始化,实例化 Camera Hal 接口 CameraHardwareInterface ->...
-> HAL 客户端(Camera.cpp)调用 connect 与服务端(CameraService.cpp)连接得到 CameraService 中的 CameraClient 的一个实例 ->服务端 CameraClient 的初始化,实例化 Camera Hal 接口 CameraHardwareInterface ->...
Bluetooth结构 1、JAVA层 frameworks/base/core/java/android/bluetooth/ 包含了bluetooth的JAVA类。...调用硬件适配层的接口system/bluetooth/bluedroid/bluetooth.c 3、bluez库 external/bluez/ 这是b
本机代理生成器:生成帮助程序C ++类供您通过JNI接口调用Java API,包括创建新实例,调用方法,获取/设置字段,定义常量。 Glue代表用于实现Java本机方法的c ++代码。 (胶水java和C ++。) 代理代表c ++类,用于从...
4. 实例化一个logger对象,调用静态函数:log4cplus::Logger::getInstance("logger_name") 5. 将appender对象绑定(attach)到logger对象,如省略此步骤,标准输出(屏幕)appender对象会绑定到logger 6. 设置logger的...
1.1.3 面向对象程序设计方法 1.1.4 最终解决方案:组件软件 1.1.5 面向对象的组件模型——COM 1.2 COM的发展历程 1.2.1 COM以前的对象技术:DDE、OLE 1、VBX控件 1.2.2 COM首次亮相:OLE2 1.2.3 Microsoft拥抱...
此外,他对Linux内核、C/C++/Python相关的技术 ,以及高性能网络服务器和多核并行开发等也有一定的研究。 目录 封面 -17 封底 489 扉页 -16 版权 -15 推荐序 -14 前言 -12 致谢 -9 目录 -7 第1章 阅读前的准备...
这些软件驱动程序通过调用 API与基础硬件平台(或微控制器)以及所连接的传感器进行。 程序员可以通过包括传感器的相应头文件并实例化关联的传感器类来访问每个传感器的接口。 在典型的用例中,构造函数根据标识...
和 C++ 有所区别的是,C# 中没有单独的声明(头)和实现(CPP)文件。所有代码(类声明和实现)都放在扩展名为 cs 的单一文件中。 看看 C# 中的 Hello World 程序。 复制内容到剪贴板 代码: using System; ...
CPP:C++代码文件 CPR:Corel提供说明书文件 CPT:Corel 照片-绘画图像 CST:Macromedia Director Cast文件 CUR:Windows光标文件 D DBF:dBASE文件,一种由Ashton-Tate创建的格式,可以被ACT!、Lipper、...
软件编程规范培训实例与练习 软件编程规范培训实例与练习 问题分类 1 逻辑类问题(A类)-指设计、编码中出现的计算正确性和一致性、程序逻辑控制等方面出现的问题,在系统中起关键作用,将导致软件死机、功能...