入门: 使用JNI 从C++代码中调用Java的静态方法
开发环境:
操作系统: (uname -a output) Linux ubuntu 3.8.0-19-generic #29-Ubuntu SMP Wed Apr 17 18:16:28 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
JDK 版本 : (java -version)
java version "1.7.0_51"
OpenJDK Runtime Environment (IcedTea 2.4.4) (7u51-2.4.4-0ubuntu0.13.04.2)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)
G++ 版本: (g++ --version) g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3
首先 Main.java 文件 :
public class Main
{
public static void test(int time )
{
System.out.println("time is " + 2*time);
} }
创建 api.cpp 文件 :
#include <jni.h>
#include <iostream>
#include <string.h>
using std::cout;
using std::endl;
using std::hex;
int main ()
{
/* where everything is defined */ JavaVM *jvm = NULL; /* denotes a Java VM */
JNIEnv *env = NULL; /* pointer to native method interface the JNI interface pointer 只在当前thread中有效*/
JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */
JavaVMOption* options = new JavaVMOption[];
options[].optionString = const_cast<char *>("-Djava.class.path=.");///usr/lib/jvm/java-7-openjdk-amd64/jre/lib /usr/lib/java vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = ;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE; /* load and initialize a Java VM, return a JNI interface
* pointer in env */
bool flag = false;
if (JNI_CreateJavaVM(&jvm,(void **) &env, &vm_args)!=JNI_OK)
{ cout << "JNI not JNI_OK" << endl; flag = true; }
if (jvm==NULL)
{ cout << "jvm is null!" << endl; flag = true; }
if (env==NULL)
{ cout << "env is null!" << endl; flag = true; }
if (flag) { cout.flush(); return -;} delete options;
/* invoke the Main.test method using the JNI */
jclass cls = env->FindClass("Main");
jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
env->CallStaticVoidMethod(cls, mid, );
/* We are done. */
jvm->DestroyJavaVM();
cout << "end of create vm \n";
return ;
}
运行脚本 :
#!/bin/sh
JNI_INCLUDE="-I/usr/lib/jvm/java-7-openjdk-amd64/include -I/usr/lib/jvm/java-7-openjdk-amd64/include/linux "
JNILIB="-L/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server" JAVASOURCE=`find . -name "*.java"`
CPPSOURCE=`find . -name "*.cpp"`
export LD_LIBRARY_PATH=/usr/lib/jvm/java--openjdk-amd64/jre/lib/amd64/server:. echo "============================================"
javac $JAVASOURCE
echo 'Java files compiled'
g++ -Wall $JNI_INCLUDE $JNILIB -L/usr/bin/java -fPIC -fpermissive $CPPSOURCE -o $test.out -ljvm
./test.out
输出脚本的结果:
Java files compiled
time is
end of create vm
问题总结 & 注意事项:
- 指定JNI的头文件正确路径
- 指定libjvm.so的正确路径, g++编译选项最后加上-ljvm (否则编译不通过)
- c++ 代码中第15行设置java.class.path时要指向你使用的类的目录 (会导致创建VM失败,aborted (cord dumped)
- -fpermissive 参数可以去掉,刚开始没有对JNI_CreateJavaVM的第二个参数强制类型转换,参数error
参考教程:
Oracle 官方指南 http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/invocation.html#wp9502
相关问题:
创建VM 失败 aborted , stackoverflow上的一个问题
入门: 使用JNI 从C++代码中调用Java的静态方法的更多相关文章
- python_代码中调用java类
1. 安装jpype (python调用java class文件用) 1.1. 自动安装:pip install jpype1 1.2. 手动方式安装jpype1 安装wheel:pip instal ...
- [转]C# 互操作性入门系列(四):在C# 中调用COM组件
传送门 C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列(二):使用平台调用调用Win32 函数 C# 互操作性入门系列(三):平台调用中的数据封送处理 ...
- Android 在C代码中调用logcat
本文给<Android java传递int类型数组给C>中添加C代码中调用logcat的功能 Android.mk文件增加以下内容 LOCAL_LDLIBS += -llog C代码中增加 ...
- Dynamics AX 2012 R2 从代码中调用SSRS Report
平时,我们制作SSRS Report的方法主要有两种:使用Query或RDP.如果需要为报表传递参数,就要在代码中为报表参数赋值,然后在代码中调用报表.下面我总结下这两种报表在代码中传参和调用的方式: ...
- 在代码中调用 mvc 4 api
mvc 4 api 的调用有很多种,最常见也最简单的一种是 用 ajax 的方式在前端界面中调用, 如果是在后台代码中调用 ,是要复杂一些,以下是 以 post 的方式调用 api 的封装好的方法: ...
- 该对象尚未初始化。请确保在所有其他初始化代码后面的应用程序启动代码中调用 HttpConfiguration.EnsureInitialized()。
WebAPI使用属性路由,配置config.MapHttpAttributeRoutes();后出现错误: System.InvalidOperationException: 该对象尚未初始化.请确保 ...
- 在php代码中调用帝国cms头部变量temp.header的方法
在php代码中调用帝国cms头部变量temp.header的方法 代码如下: <?php require("../e/class/connect.php"); if(!def ...
- 在scala中调用java代码
详细代码请见https://github.com/lujinhong/scalademo 在scala中调用java代替非常非常简单,直接调用即可 (一)一个简单示例 1.创建一个java类 pa ...
- Android JNI之C/C++层调用JAVA
转载请声明:原文转自:http://www.cnblogs.com/xiezie/p/5930032.html 从C/C++层调用JAVA层代码步骤: 1. 在JAVA类中创建java方法和本地方法 ...
随机推荐
- 微信公共号的PHP开发(基础篇)——玩一下
最近没事儿开了个微信号,写点东西给家人啊什么的看,你们想看的话就这个嘛: 然后就意外的看到imooc上的微信公众号开发相关了.每天科研的累累的,做点这个不是很累的东西吧. 微信公共号开发 一.基础 1 ...
- 计算机网络-IP类型判断
第一个类别为A类,最后一个类别为E类,前边三个类别(A类.B类和C类)被用来标识工作站.路由器.交换机以及其他设备,而最后两个类别(D类和E类)被保留做特殊用途. 一个IP地址由32个比特位构成,这就 ...
- pyqt5-为QListWidget添加右键菜单
如何在pyqt5下为QListWidget添加右键菜单? 能百度到的均是pyqt4下的,有些貌似并不好用. 在尝试了很多方法后,下面贴出可用的方法: from PyQt4 import QtCore, ...
- CCF考试
第八次CCF考试记录 代码还不知道对不对,过两天出成绩. 成绩出来了,310分. 100+100+100+10+0: 考试13:27开始,17:30结束,提交第4题后不再答题,只是检查前四题的代码 第 ...
- 第23章 java线程通信——生产者/消费者模型案例
第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...
- HOLOLENS程序发布,这个界面调用的图片
SplashScreen.scale-200.png 1240 x 600
- Android 官方推荐 : DialogFragment 创建对话框
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37815413 1. 概述 DialogFragment在android 3.0时 ...
- 10款.net 图形插件
在如今这个读图时代,图形图表的可视化数据表现形式已成为一种趋势.因为图表能直观的展示信息.对比和趋势等,所以许多项目开发中都需要用到图表控件,而很多图表控件都是在.NET平台下开发的,今天就为大家推荐 ...
- Python-02-基础
一.数字 int(有符号整型) Python3可以处理任意大小的整数,当然包括负整数. int = 20 print int long(长整型) Python3中不再区分整型和长整型. float(浮 ...
- c#导出bugfree3.0的数据到禅道
环境:vs2012MVC4项目,mysql server5.6 准备:bugfree的数据库导出后.sql文件,禅道7.1的数据库文件 基本过程:这是个笨办法,也没有优化过代码,导入数据时候比较慢.禅 ...