在Java代码中通过JNI调用C函数的步骤如下:

第一步:编写Java代码

第二步:编译Java代码(javac Java文件)

第三步:生成C代码头文件(javah java类名,自动生成)

第四步:编写C代码(实现C代码头文件里面的函数)

第五步:生成C共享库(使用工具编译生成C共享库,win下面为dll文件,Linux下面为so文件)

第六步:运行Java程序(java 类名)

一、编写Java代码

首先编写调用C语言的Java源代码HelloJNI.java

public class HelloJNI {

native void printHello();

native void printString(String str);

static {

System.loadLibrary("hellojni");

}

public static void main(String[] args) {

// TODO Auto-generated method stub

HelloJNI myJNI = new HelloJNI();

myJNI.printHello();

myJNI.printString("Hello world form printString function!");

}

}

说明:

1. 在Java类中,使用”native”关键字,声明本地方法,该方法与用C/C++编写的JNI本地函数相对应。”native”关键字告知Java编译器,在Java代码中带有该关键字的方法只是声明,具体由C/C++等其它语言编写实现。

2. 在Java类中声明了本地方法之后,接下来,调用System.loadLibrary()方法,加载具体实现本地方法的C运行库(在Java中加载本地运行库通常使用静态块(static block))。System.loadLibrary()方法加载由字符串参数指定的本地库,在不同操作系统平台下,加载的C运行库不同。在Window下面,调用System.loadLibrary(“hellojni”),则hellojni.dll会被加载;在Linux下面,则会加载libhellojni.so文件。

二、编译Java代码

使用javac编译java源代码

javac HelloJNI.java

三、生成C代码头文件

使用javah自动生成C代码头文件

javah HelloJNI

生成的头文件HelloJNI.h见下:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for class HelloJNI */

#ifndef _Included_HelloJNI

#define _Included_HelloJNI

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: HelloJNI

* Method: printHello

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_HelloJNI_printHello

(JNIEnv *, jobject);

/*

* Class: HelloJNI

* Method: printString

* Signature: (Ljava/lang/String;)V

*/

JNIEXPORT void JNICALL Java_HelloJNI_printString

(JNIEnv *, jobject, jstring);

#ifdef __cplusplus

}

#endif

#endif

四、编写C代码

实现C头文件中的方法,hellojni.c文件见下:

#include "HelloJNI.h"

#include

JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *env, jobject obj)

{

printf("Hello world!\n");

return ;

}

JNIEXPORT void JNICALL Java_HelloJNI_printString(JNIEnv *env, jobject obj, jstring string)

{

const char * str = (*env)->GetStringUTFChars(env,string,0);

printf("%s!\n",str);

return ;

}

说明:

1、GetStringUTFChars ()是JNI函数,用来将Java字符串转换成C语言字符串。JNI提供了多种JNI函数,用来处理C字符串与Java字符串的转换,具体参见http://blog.csdn.net/qinjuning/article/details/7595104

五、生成C共享库

在Linux下测试,书写makefile文件,编译刚才所写的C代码,生成.so文件;

makefile文件见下:

libhellojni.so:hellojni.o makefile

gcc -Wall -rdynamic -shared -o libhellojni.so hellojni.o

hellojni.o:hellojni.c HelloJNI.h

gcc -Wall -c hellojni.c -I./ -I/usr/lib/jdk/include -I/usr/lib/jdk/include/linux -fPIC

cl:

rm -rf *.o *.so

使用make命令编译

make

说明:

1、生成的so文件必须命令为libhellojni.so,与java代码中的System.loadLibrary("hellojni")对应;

2、在编译时,必须加上-fPIC,否则,编译时报以下错误:

/usr/bin/ld: hellojni.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC

hellojni.o: could not read symbols: Bad value

collect2: ld 返回 1

make: *** [hellojni.so] 错误 1

3、gcc和rm前面必须是一个tab空格,否则makefile格式不正确;

六、运行java程序

在运行java程序之前,要把生成的so文件加入LD_LIBRARY_PATH中,如下:

export LD_LIBRARY_PATH=./

否则,在运行java程序的时候报错,错误信息见下:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no hellojni in java.library.path

at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738)

at java.lang.Runtime.loadLibrary0(Runtime.java:823)

at java.lang.System.loadLibrary(System.java:1028)

at HelloJNI.(HelloJNI.java:7)

Could not find the main class: HelloJNI. Program will exit.

运行java程序:

java HelloJNI

结果见下:

Hello world!

Hello world form printString function!!

在java 中调c_在Java中调用C相关推荐

  1. java 执行cmd 堵塞_java中调用cmd命令被阻塞无法返回和继续执行

    在项目中用到了数据库的备份和恢复功能,就通过java的Runtime.getRuntime().exec()来调用cmd或者linux命令来导出和导入.sql文件.但是在执行恢复时,程序一直被阻塞,没 ...

  2. java调c++代码_Java中调用C++代码的实现 | 学步园

    JNI为  Java Native Interface 即Java本地接口,使用此种方式可以对C/C++代码进行调用,其在本质上是对C/C++生成的动态库进行调用而不是直接对C/C++代码进行调用 J ...

  3. Java乔晓松-android中调用系统拍照功能并显示拍照的图片

    android中调用系统拍照功能并显示拍照的图片 如果你是拍照完,利用onActivityResult获取data数据,把data数据转换成Bitmap数据,这样获取到的图片,是拍照的照片的缩略图 代 ...

  4. java 执行oracle 存储过程_oracle--在java中调用存储过程和存储函数

    在java中调用存储过程和存储函数 存储过程: 查询某个员工的姓名 月薪 职位: create or replace procedure queryempinfo(eno in number, pen ...

  5. java 执行js脚本_java中调用js脚本

    JDK1.6加入了对Script(JSR223)的支持.这是一个脚本框架,提供了让脚本语言来访问Java内部的方法.你可以在运行的时候找到脚本引擎,然后调用这个引擎去执行脚本.这个脚本API允许你为脚 ...

  6. ajax 调用java类_在ajax中调用java方法

    AJAX是Asynchronous JavaScript And XML的首字母缩写.它提供了异步与服务器通信的能力. 要简单地解释一下,您可以向服务器发送请求并继续与用户进行用户交互.您无需等待服务 ...

  7. java主类调用数组_用java编写在主函数中调用数组

    importjava.util.Scanner;publicclassja{publicstaticvoidmain(Stringargs[]){Scannerscanner=newScanner(S ...

  8. 回顾基础,Java如何在main方法中调用自身的main方法

    先来回顾下main方法组成结构: public class Test {public static void main(String[] args) {System.out.println(" ...

  9. java获取接口数据类型_java中调用第三方接口获取数据的方式

    //get请求方式 private String getInfo(Map params,String URL) { // 创建Httpclient对象 CloseableHttpClient http ...

最新文章

  1. 如果要存 IP 地址,用什么数据类型比较好?大部人都会答错!
  2. 从终端运行python程序
  3. Unity3D 游戏引擎之脚本实现模型的平移与旋转(六)
  4. Python相对、绝对导入浅析
  5. iOS----------iPhone导出手机所有短信
  6. System.Data.Entity.Core.MetadataException:“Unable to load the specified metadata resource.”
  7. [unity3d]自定义鼠标指针
  8. 【Java并发编程】:Runnable和Thread实现多线程的区别
  9. NOIP模拟赛20161016R2
  10. CSRF与XSS攻击的原理与防范
  11. Linux是实时系统还是分时操作系统?
  12. 斗鱼tv 服务器响应失败,斗鱼tv打不开怎么办 斗鱼直播打不开得解决办法
  13. java怎么控制数据权限_Java权限控制算法
  14. 最新emoji表情代码大全_NO.3 如何用Emoji迷惑人类
  15. 英制 mil 和公制 mm 的换算
  16. Python与SEO,搜狗站长平台网站提交POST源码
  17. 安装MathType后,不能快捷键复制粘贴
  18. 如何将Figma转成蓝湖教程
  19. 最新唯美520表白纪念网页HTML源码+UI超级好看
  20. 8421码到5421码的转换_余三码8421bcd码转换电路设计的接线方法

热门文章

  1. https://www.usb.org/
  2. Intel 64 and IA-32 Architectures Instruction Format 指令格式
  3. libevent的两个服务端、客户端示例(C语言)
  4. 无盘服务器性能测试,无盘系统性能测试及结语
  5. jupyter notebook 快捷键设置字体大小_你可能并不知道这样定制炫酷的jupyter主题
  6. idea下如何正确导入多个module
  7. mbsfn子帧_LTE多媒体广播多播业务关键技术研究
  8. pc控制iphone的软件_哪个备忘录便签app可以和PC电脑一块儿用
  9. php分页函数代码,PHP分页函数代码分享
  10. vmware传东西到linux后文件变小,在VMWARE的Linux虚拟机上删除大容量文件后硬盘空间大小还不变怎么办?虚拟机虚拟机的各种应用及问题...