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

 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. 3.JMeter添加集合点

    1.JMeter的集合点是通过添加定时器来完成的,在做性能测试时,真正的并发是不可能的,为了更真实的模拟并发场景,因此在需要压测的地方设置集合点,即可一起操作发送请求. 2.JMeter添加定时器,右 ...

  2. Android.mk语法解析

    Android.mk 相当于 Linux 中的 Makefile 文件,用来向安卓系统描述如何编译源代码.该文件会被编译器解析多次,所以尽量减少在 Android.mk 中声明变量. Android. ...

  3. strcpy手写——面试

    #include<stdio.h> #include<string.h> ]={]; char* strcpy(char *to,char *from){ if(NULL==t ...

  4. centos7下安装docker 17.x

    docker的17.X版本与以前的docker安装有些不同,参考了下这篇文章http://www.itmuch.com/docker/docker-2/,以下是我的docker 17.X版本安装过程, ...

  5. Exception in thread "main" java.lang.UnsupportedClassVersionError: com/crack

    执行一个jar文件的时候抛异常了 Exception in thread "main" java.lang.UnsupportedClassVersionError: com/cr ...

  6. 用 Linux blkid 命令查找块设备详情

    今天我们将会向你展示如何使用 lsblk 和 blkid 工具来查找关于块设备的信息,我们使用的是一台安装了 CentOS 7.0 的机器. lsblk lsblk 是一个 Linux 工具,它会显示 ...

  7. Win10系统WMIProviderHost进程占用CPU过高

    “WMI Provider Host“占用了过多CPU资源导致系统卡顿,该如何解决这个问题呢? 解决方法: 可以尝试关闭Windows防火墙服务来解决这个问题. 1.按住win+R,输入service ...

  8. idea 注册码 地址:

    http://idea.lanyus.com IntelliJ IDEA 注册码 *.lanyus.com及*.qinxi1992.cn下的全部授权服务器已遭JetBrains封杀 请搭建自己的Int ...

  9. JDK 9 & JDK 10 新特性

    JDK 9 新增了不少特性,官方文档:https://docs.oracle.com/javase/9/whatsnew/toc.htm#JSNEW-GUID-527735CF-44E1-4144-9 ...

  10. java代码----substring()方法是按索引截取字符串。。。下标0开始

    总结:按照索引substring(2,5);意思是从字符串的索引为2开始(包括)到第6个字符(不包括)的位置的截取部分 package com.s.x; //substring public clas ...