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

 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. 使用zabbix监控mysql

    系统版本: centos6 x86_64 mysql版本: mysql5.6 实施目的: 监控mysql 客户端配置: 1.准备工作:搭建zabbix服务,使服务端客户端连接成功,并有基础监控项 2. ...

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

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

  3. python3第一次作业

    需要一个文件users,里面有用户名密码以及是否锁定的标识符 lzd--123--1wdl--123--0lw--123--0aaa--123--0bbb--123--0ccc--123--1ddd- ...

  4. Intellij解决版本冲突时,merge界面各区块颜色区分

    灰色:删除 蓝色:改变 绿色:新增 红色:冲突

  5. python写个Hack Scan

    前言: 之前逛SAFEING极客社区的时候 发现一款黑市卖2000多的软件,后面下载了 打不开.发现config文件里面有些不错的东西.总结了一下 有了以下的脚本. 脚本用处: [1]探测CMS(不敢 ...

  6. ubuntu 解决“无法获得锁 /var/lib/dpkg/lock -open”的方法

      在ubuntu系统终端下,用apt-get install 安装软件的时候,如果在未完成下载的情况下将终端中断,此时 apt-get进程可能没有结束.结果,如果再次运行apt-get instal ...

  7. 同源策略、CORS

    一.同源策略 同源策略(Same origin policy) 是一种约定, 它是浏览器最核心也是最基本的安全功能 , 如果缺少了同源策略, 则浏览器的正常功能可能都会受影响 , 可以说web是构建在 ...

  8. Spring高级话题

    Spring Aware 在实际项目中,你不可避免的要用到spring容器本身的功能资源,这时你的bean要意识到spring容器的存在,才能调用spring提供的资源.spring aware本来就 ...

  9. prettytable模块(格式化打印内容)

    1.查看系统是否已经安装prettytable模块 2.下载prettytable模块 登陆:https://pypi.python.org/pypi/PrettyTable 3.安装PrettyTa ...

  10. Please specify exact device preset UUID

    Please specify exact device preset UUID 重启RAD IDE,重新选择 IOS Simulator ,iphone 机型!