入门: 使用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方法和本地方法 ...
随机推荐
- Excel自文本导入内容时如何做到单元格内换行
前言:今天在处理数据的时候,在数据库中用到了\n换行符号,目的是在同表格内做到数据多行显示,比如 字段名1 字段名2 字段名3 1 数据一行 数据二行 数据三行 例子是在sql查询后的结果 ...
- 【2016-10-17】【坚持学习】【Day8】【简单工厂模式】
今天学习简单工厂模式, 结构 一个抽象产品 多个具体产品 一个工厂类,通过传入参数,new出不同的产品 代码: abstract class Product { //所有产品类的公共业务方法 publ ...
- mysql 加锁测试
今天研究cobar,做执行时间测试,需要对表记录加锁.用了以下两种方式为表记录加锁. 第一种方式: begin; //开始事务 select * from 表名 ( where ……) for ...
- 熟悉MyEclipse
资源网址:http://www.myeclipsecn.com/learningcenter/ 20151126 [从这里开始]量身打造自己的MyEclipse(多图) 主要讲在MyEclipse里面 ...
- 解决asp.net(C#)中 DataTime 空值 null为0001-01-01
SqlServer中的datetime类型的空值和c#中的DateTime的空值的研究 在SqlServer 2000中datetime 的空值即默认值为1900-01-01 00:00:00,C#中 ...
- Spring WebService 和 搜索
参考文章: http://blog.csdn.net/kkdelta/article/details/7290769 云计算中主流的Web服务有两种: 1.WebService.内容比较沉重,技术人员 ...
- jQuery浏览器类型判断和分辨率判断
< DOCTYPE html PUBLIC -WCDTD XHTML TransitionalEN httpwwwworgTRxhtmlDTDxhtml-transitionaldtd> ...
- 序列化效率比拼——谁是最后的赢家Newtonsoft.Json
前言:作为开发人员,对象的序列化恐怕难以避免.楼主也是很早以前就接触过序列化,可是理解都不太深刻,对于用哪种方式去做序列化更是随波逐流——项目中原来用的什么方式照着用就好了.可是这么多年自己对于这东西 ...
- C#字符串操作 取文本左边 取文本右边 取文本中间 取文本中间到List集合 指定文本倒序
/// <summary> /// 取文本左边内容 /// </summary> /// <param name="str">文本</pa ...
- php设置浏览器响应时间
ini_set('max_execution_time', '0'); ‘0’表示不受时间限制,一般默认30s;