JAVA本地调用(JNI- java调用c)
记录一下工作内容,对术语了解不多,暂且这样记着吧。
java调用c
一、写jni的步骤如下:
1.创建java类,定义接口函数,使用native修饰;
2.将java类编译成class;
3.将class编译成*.h头文件;
4.在c/c++中实现java定义的接口函数;
5.将该c/c++的实现导出动态链接库;
6.将动态链接库放到java的库路径;
7.使用。
二、应该注意的一些问题:
1.注意该java类所在的包,包会影响导出的头文件的名称,还会影响到头文件的生成;代码中不要出现中文;
2.使用javac将类编译成class文件,该文件会出现在java文件同一目录下;
3.使用javah将class文件编译成头文件,这一步需要注意,如果该类在某个包下,需要在src路径下进行编译,最后给出例子。
4.在c/c++中实现时注意java类型和c/c++类型间的转换,我遇到的是jstring转换成char*的问题。
对于如下函数
JNIEXPORT void JNICALL Java_com_bbwang_JniTest_printMsg
(JNIEnv *env, jobject o, jstring str)
{
}
如果是c实现,调用GetStringUTFChars时应该如下调用
const char *cstr = (*env)->GetStringUTFChars (env, str, NULL);
如果是c++实现,调用GetStringUTFChars时需要如下操作
const char *cstr = env->GetStringUTFChars (str, NULL);
5.build时指定导出dll,需要将%JAVA_HOME%\include和%JAVA_HOME%\include\win32包含到additional include directories;
6.在java中使用时只需要java的接口定义文件和导出的dll,具体使用时需要LoadLibrary,dll放在java.library.path下;
三、具体实现的例子
1.先是java文件,我的文件在com.bbwang包下!:
package com.bbwang;
public class JniTest
{
public native void printMsg(String str);
public native long add(int left, int right);
public native long minus(int left, int right);
} // class JniTest end
2.编译
找到src路径下
javac com\bbwang\JniTest.java 编译出class
javah com.bbwang.JniTest 编译出头文件,头文件在src目录下,名称是com_bbwang_JniTest.h,头文件内容贴出来:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_bbwang_JniTest */
#ifndef _Included_com_bbwang_JniTest
#define _Included_com_bbwang_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_bbwang_JniTest
* Method: printMsg
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_bbwang_JniTest_printMsg
(JNIEnv *, jobject, jstring);
/*
* Class: com_bbwang_JniTest
* Method: add
* Signature: (II)J
*/
JNIEXPORT jlong JNICALL Java_com_bbwang_JniTest_add
(JNIEnv *, jobject, jint, jint);
/*
* Class: com_bbwang_JniTest
* Method: minues
* Signature: (II)J
*/
JNIEXPORT jlong JNICALL Java_com_bbwang_JniTest_minus
(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
4.c实现
#include <stdio.h>
#include <stdlib.h>
#include "com_bbwang_JniTest.h"
/*
* Class: com_bbwang_JniTest
* Method: printMsg
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_bbwang_JniTest_printMsg
(JNIEnv *env, jobject o, jstring str)
{
const char *cstr = (*env)->GetStringUTFChars (env, str, NULL);
fprintf (stdout, "from native method, msg = %s\n", cstr);
(*env)->ReleaseStringUTFChars (env, str, cstr);
}
/*
* Class: com_bbwang_JniTest
* Method: add
* Signature: (II)J
*/
JNIEXPORT jlong JNICALL Java_com_bbwang_JniTest_add
(JNIEnv *env, jobject o, jint left, jint right)
{
return left + right;
}
/*
* Class: com_bbwang_JniTest
* Method: minues
* Signature: (II)J
*/
JNIEXPORT jlong JNICALL Java_com_bbwang_JniTest_minus
(JNIEnv *env, jobject o, jint left, jint right)
{
return left - right;
}
5.导出dll
6.可以使用了
我将dll放到了%JAVA_HOME%\bin目录下,调用的文件内容如下:
package com.bbwang;
public class ForTest
{
static
{
System.loadLibrary("JniTest");
}
public static void main(String[] args)
{
// 不知道java.library.path在哪就直接打出来撒
// System.out.println(System.getProperty("java.library.path"));
System.out.println("test start");
JniTest jt = new JniTest();
jt.printMsg("native method start");
long result = jt.add(1,2);
System.out.println(result);
result = jt.minus(6,2);
System.out.println(result);
jt.printMsg("native method end");
}
} // class ForTest end
7.恩,可以看到结果了:
test start
3
4
from native method, msg = native method start
from native method, msg = native method end
结果还是比较神奇的,消息竟然是最后打出来的
JAVA本地调用(JNI- java调用c)的更多相关文章
- java并发笔记之java线程模型
警告⚠️:本文耗时很长,先做好心理准备 java当中的线程和操作系统的线程是什么关系? 猜想: java thread —-对应-—> OS thread Linux关于操作系统的线程控制源码: ...
- java本地方法如何调用其他程序函数,方法详解2
Java调用本地方法(JNI浅谈) (2006-11-27 14:55:36) 转载▼ 分类: Java类文章 本人在项目开发实践中的总结和体会 前段时间公司 ...
- java本地方法如何调用其他程序函数,方法详解
JNI是Java Native Interface的缩写,中文为JAVA本地调用.从Java 1.1 开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许J ...
- java通过JNI接口调用C语言-初级
JNI(java native interface):即java本地调用C的接口. 先看整体运行: 下面是过程: #vim test.java public class test{ public na ...
- cocos2d-x中使用JNI的调用JAVA方法
用cocos2d-x公布Android项目时.都应该知道要用JAVA与C/C++进行交互时会涉及到JNI的操作(Java Native Interface).JNI是JAVA的一个通用接口.旨在本地化 ...
- [JNI] Java 调用 C++ dll
首先介绍一下JNI吧! JNI 是Java提供的一个用于调用本地接口的接口层,位于Java代码 和 本地代码之间的一层:主要功能是 数据类型的转换,还有就是通过这一层来调用本地代码! 下面就说说Jav ...
- Android与JNI(二) ---- Java调用C++ 动态调用
目录: 1. 简介 2. JNI 组件的入口函数 3. 使用 registerNativeMethods 方法 4. 测试 5. JNI 帮助方法 6. 参考资料 1. 简介 Android与JNI( ...
- java native interface JNI 调用Java方法
在上一篇文章中介绍了JNI.以及java调用JNI.这篇讲一下 JNI调用java方法. 通过使用合适的JNI函数,你能够创建Java对象,get.set 静态(static)和 实例(instanc ...
- Java採用JNI调用VC++生成的dll(Java与C++交互)
应项目需求,须要android调用java,java再调用C++实现android一个图片匹配的功能,我们作为java组须要和C++和Android进行交互.以下是java和C++採用JNI的方式进行 ...
- JNI——Java调用C/C++函数
从C/C++到Java,再从Java回到C/C++,今天终于有机会了解了连接Java.C/C++的桥梁——JNI.哈哈!分享一下! 一.简介 JNI是Java native interface的简 ...
随机推荐
- 搭建基于hyperledger fabric的联盟社区(三) --生成公私钥证书及配置文件
一.生成公私钥和证书 Fabric中有两种类型的公私钥和证书,一种是给节点之前通讯安全而准备的TLS证书,另一种是用户登录和权限控制的用户证书.这些证书本来应该是由CA来颁发,但是目前只有两个社区,所 ...
- javascript正则表达式定义(语法)
正则表达式的2种定义方法:一种是直接调用RegExp(),第二种是直接用字面量来定义,即var re = /正则规则/; 2种定义方法本质都是调用RegExp()方法 在调用同一段正则代码的时候,EC ...
- Jetty实战(杂七杂八)
最近开始选择JETTY作为服务器了,乘这现在空闲点学习了些JETTY的部署知识,原来她真的跟TOMCAT很类似,先总结如下: 部署应用方法(下载好jetty); 方法一: 直接将应用的 war包放在j ...
- Python基础之元组tuple(带了枷锁的列表)
元组不能直接插入删除修改元素. 逗号是关键 创建空元组 元组的一些操作符 别忘了逗号,"*"重复操作符也可以使用 元组通过切片间接更新 插入元素,可以使用拼接操作符(“+”) &g ...
- Warning: require(D:\wamp\www\glink-smart\bootstrap/../vendor/autoload.php): failed to open stream: No such file or directory in D:\wamp\www\glink-smart\bootstrap\autoload.php on line 1
Laravel访问出错错误信息:`Warning: require(/vendor/autoload.php): failed to open stream: No such file or dire ...
- ColorPic 一套簡單好用的顏色選擇器!
做美工的時候,常常會有配色.抓取顏色及獲取顏色代碼的困擾,專業人士可能有很好的工具來協助,但對於偶爾需要或非經常接觸美工的人來說,即便是有很好的工具,也還要花很多時間進行學習,常常就是看到一個漂亮的顏 ...
- ThinkPHP Http工具类(用于远程采集 远程下载) phpSimpleHtmlDom采集类库_Jquery筛选方式 使用phpQuery轻松采集网页内容http://www.thinkphp.cn/extend/541.html
[php]代码库 view sourceprint? <?php // +------------------------------------------------------------ ...
- django-cbv模式-csrf中间件
1. django模式 def users(request): user_list = ['alex','oldboy'] return HttpResponse(json.dumps((user_l ...
- 第六章 通过Service访问Pod(下)
6.4 外网如何访问service (1)ClusterIp: Service通过Cluster内部的IP对外提供服务,只有Cluster内的节点和Pod可以访问,这是默认的Service类型. (2 ...
- 侯捷 c++面向对象程序设计
基础知识 基于对象:Object Based 面对的是单一class的设计. 面向对象:Object Oriented 面对的是多重classes的设计,涉及到类和类之间的关系. 课程中设计到两种不同 ...