Java中调用C库函数

写在最前面
Java中调用C库函数,依赖JNI,本文使用一个非常简单的例子来说明JNI开发流程,具体步骤如下:

第一步:编写Java代码

第二步:编译Java代码

第三步:生成C语言头文件

第四步:编写C代码

第五步:生成C共享库

第六步:运行Java程序

注:本文中将仅在Java代码中声明的方法称为本地方法,使用C/C++实现的函数称为本地函数。

第一步:编写Java代码
若想在Java代码中通过JNI调用C函数,首先在Java类中声明本地方法,本地方法仅在Java程序中进行声明,使用C/C++等本地语言来实现。

如下代码HelloJNI.java

1 class HelloJNI
  2 {
  3     // 本地方法声明
  4     native void printHello();
  5     native void printString(String str);
  6 
  7     // 加载库
  8     static{ System.loadLibrary("hello"); }
  9 
 10     public static void main(String args[])
 11     {
 12         HelloJNI myJNI = new HelloJNI();
 13 
 14         // 调用本地方法(实际调用的事使用C语言编写的JNI本地函数)
 15         myJNI.printHello();
 16         myJNI.printString("Hello World from printString fun");
 17     }
 18 }

在Java中,使用“native”关键字,声明本地方法,该方法与用C/C++编写的JNI本地函数相对应。
如下,不同平台下System.loadLibrary()方法加载的C运行库

操作系统平台    System.loadLibrary()方法的参数    实际加载的C运行库
Windows    hello    HelloJNI.dll
Linux    hello    HelloJNI.so
Mac    hello    libHelloJNI.jnilib

第二步:编译Java代码
使用Java编译器(javac),编译Java源代码,命令如下

javac HelloJNI.java
编译好HelloJNI.java后,生成HelloJNI.class
第三步:生成C语言头文件
使用javah命令生成C语言头文件,命令如下

javah HelloJNI
执行之后,生成HelloJNI.h头文件,文件内容如下
 1 /* DO NOT EDIT THIS FILE - it is machine generated */
  2 #include <jni.h>
  3 /* Header for class HelloJNI */
  4 
  5 #ifndef _Included_HelloJNI
  6 #define _Included_HelloJNI
  7 #ifdef __cplusplus
  8 extern "C" {
  9 #endif
 10 /*
 11  * Class:     HelloJNI
 12  * Method:    printHello
 13  * Signature: ()V
 14  */
 15 JNIEXPORT void JNICALL Java_HelloJNI_printHello
 16   (JNIEnv *, jobject);
 17 
 18 /*
 19  * Class:     HelloJNI
 20  * Method:    printString
 21  * Signature: (Ljava/lang/String;)V
 22  */
 23 JNIEXPORT void JNICALL Java_HelloJNI_printString
 24   (JNIEnv *, jobject, jstring);
 25 
 26 #ifdef __cplusplus
 27 }
 28 #endif
 29 #endif

第四步:编写C代码
在C函数原型文件生成后,开始编写C代码,HelloJNI.c,如下

1 #include "HelloJNI.h"
  2 #include <stdio.h>
  3 
  4 JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *env, jobject object)
  5 {
  6     printf("Hello World!\n");
  7     return;
  8 }
  9 
 10 JNIEXPORT void JNICALL Java_HelloJNI_printString(JNIEnv *env, jobject object, jstring string)
 11 {
 12     // 将 Java String转换为C字符串
 13     const char *str = (*env)->GetStringUTFChars(env,string,0);
 14     printf("%s!\n", str);
 15 
 16     return;
 17 }
第五步:生成C共享库
mac环境下使用如下命令生成动态链接库

gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/include/ HelloJNI.c -o libHelloJNI.jnilib

后面的libHelloJNI.jnilib就是我们需要的动态链接库,但是执行这个命令的时候报了如下错误
In file included from HelloWorldImpl.c:1:
/Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/include/jni.h:45:10: fatal error:
      'jni_md.h' file not found
#include "jni_md.h"
         ^
1 error generated.
提示jni_md.h这个文件找不到;我们执行下面的命令拷贝一份
sudo cp /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/include/darwin/jni_md.h /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/include
然后再执行生成动态库的命令即可。

第六步:运行Java程序
最后运行java程序,如下命令

java HelloJNI
即可得到如下输出结果
Hello World!
Hello World from printString fun!
总结
通过以上步骤,我们知道了Java本地方法如何通过JNI链接到C函数,以及具体实现等

最后,做个小结,梳理一下

(1)在Java类中声明本地方法

(2)使用javah命令,生成包含JNI本地函数原型的头文件

(3)实现JNI本地函数

(4)生成C共享库

(5)通过JNI,调用JNI的本地函数
--------------------- 
来源:CSDN 
转自:https://blog.csdn.net/joeysheng/article/details/65446025 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值