记录一下工作内容,对术语了解不多,暂且这样记着吧。

 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)的更多相关文章

  1. java并发笔记之java线程模型

    警告⚠️:本文耗时很长,先做好心理准备 java当中的线程和操作系统的线程是什么关系? 猜想: java thread —-对应-—> OS thread Linux关于操作系统的线程控制源码: ...

  2. java本地方法如何调用其他程序函数,方法详解2

    Java调用本地方法(JNI浅谈) (2006-11-27 14:55:36) 转载▼   分类: Java类文章                本人在项目开发实践中的总结和体会     前段时间公司 ...

  3. java本地方法如何调用其他程序函数,方法详解

    JNI是Java Native Interface的缩写,中文为JAVA本地调用.从Java 1.1 开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许J ...

  4. java通过JNI接口调用C语言-初级

    JNI(java native interface):即java本地调用C的接口. 先看整体运行: 下面是过程: #vim test.java public class test{ public na ...

  5. cocos2d-x中使用JNI的调用JAVA方法

    用cocos2d-x公布Android项目时.都应该知道要用JAVA与C/C++进行交互时会涉及到JNI的操作(Java Native Interface).JNI是JAVA的一个通用接口.旨在本地化 ...

  6. [JNI] Java 调用 C++ dll

    首先介绍一下JNI吧! JNI 是Java提供的一个用于调用本地接口的接口层,位于Java代码 和 本地代码之间的一层:主要功能是 数据类型的转换,还有就是通过这一层来调用本地代码! 下面就说说Jav ...

  7. Android与JNI(二) ---- Java调用C++ 动态调用

    目录: 1. 简介 2. JNI 组件的入口函数 3. 使用 registerNativeMethods 方法 4. 测试 5. JNI 帮助方法 6. 参考资料 1. 简介 Android与JNI( ...

  8. java native interface JNI 调用Java方法

    在上一篇文章中介绍了JNI.以及java调用JNI.这篇讲一下 JNI调用java方法. 通过使用合适的JNI函数,你能够创建Java对象,get.set 静态(static)和 实例(instanc ...

  9. Java採用JNI调用VC++生成的dll(Java与C++交互)

    应项目需求,须要android调用java,java再调用C++实现android一个图片匹配的功能,我们作为java组须要和C++和Android进行交互.以下是java和C++採用JNI的方式进行 ...

  10. JNI——Java调用C/C++函数

    从C/C++到Java,再从Java回到C/C++,今天终于有机会了解了连接Java.C/C++的桥梁——JNI.哈哈!分享一下!   一.简介 JNI是Java native interface的简 ...

随机推荐

  1. nagios(centreon)监控Linux日志

    1 将check_log3.pl下载后放到客户端服务器的插件文件夹[root@SSAVL2475 libexec]# cp /tmp/check_log3.pl  /usr/local/nagios/ ...

  2. Qt学习笔记(1) hello world

    Qt的简介: Qt是一个跨平台的C++ GUI库实现,原本只是以为它只提供一些图形接口,看来我还是低估了它,采用文档Qt学习之路2开始学习,不知道这个文档是不是有点老了,管他呢,先了解下. 搭建环境: ...

  3. linux下 tomcat 日志乱码/中文链接404

    1 日志乱码: JDK引用的设置 Java引用参数添加”-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8” 将上面参数添加到Catalina.sh中JAVA ...

  4. Hessian简要入门

      原本系统之间通信采用Restful Web Service,但其中没有考虑安全性问题,因此决定使用稍微复杂点的二进制协议,Hessian服务.   Hessian是一个轻量级的Remoting O ...

  5. Windows Server 2012十大实用快捷键组合

    在本文中,我们将一起体验快捷键如何在微软最新服务器操作系统中帮助用户提升工作效率. 微软推出的最新服务器操作系统比我印象中任何一款前代Windows Server产品都依赖于键盘操作——当然,这些产品 ...

  6. 使用jQuery Pagination Plugin实现分页效果

    最近使用分页这个基础效果较为频繁,而项目前端页面使用的是纯静态的HTML,自己之前写的JSP中的分页就用不成了:项目中也引入了Bootstrap,本来想使用Bootstrap中的分页样式,但发现其样式 ...

  7. MyBatis的适用场景和生命周期

    MyBatis使用场景 对比Hibernate和MyBatis是我们常见的话题,Hibernate作为常用的ORM框架,它使用起来简单易懂,对于SQL语言的封装,让对于SQL并不是很熟练的程序员也可以 ...

  8. Thread pools & Executors

    Thread pools & Executors Run your concurrent code in a performant way All about thread pools # H ...

  9. SQL Server Management Studio (SSMS)

    最新的SQLServer数据库已经不集成SQL Server Management Studio需要单独下载安装. https://docs.microsoft.com/zh-cn/sql/ssms/ ...

  10. fiddler的介绍

    一.Fiddler是一个http协议代理工具,主要有以下功能: 1.监控http/https流量.截获http/https请求 2.查看并调试截获到的请求 3.伪造请求与响应 4.测试网站性能 5.解 ...