java(JNI)调用c/c++动态链接库 linux

         已经半年没有更新博客了,今天终于找到了可以写的东西,虽然这种东西写过的大神已经很多了,我只是新瓶装旧酒而已。写点自己的感悟和大家分享,也帮助自己加深记忆。

         OK~言归正传,相信很多童鞋肯定和我一样喜欢用c++处理一些算法问题,但是有时候应用是java写的,这个时候就非常希望能够在java代码里调用c++的模块了。感谢JNI的存在~

         下面,就介绍JNI的使用,以及关于c/c++动态链接库的编译问题了。

         首先,先编写一个java文件,这个文件作为调用c/c++的载体吧,例子:

         

public class Test{
     public native void hello();
     public static void main(String[] args){
         System.loadLibrary("Test");
         Test tt = new Test();
         tt.hello();
     }
}
          在这分代码里,hello方法就是之后需要用c/c++实现的方法,然后想调用只要new一个Test类就好了。

          System.loadLibrary("Test")这一行表示加载Test这个动态链接库(在linux(unix)里对应的文件就是libTest.so,如果字符串是XXX,那么文件就是libXXX.so,这个字符串很随意,不一定要和java文件的类名一致)

          然后就是编译该代码了:javac  Test.java

          再之后,还得生成相应动态链接库的头文件:javah  Test,输入完这个命令之后,当前目录下就会多出Test.h这个文件,内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Test */

#ifndef _Included_Test
#define _Included_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Test
 * Method:    hello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_Test_hello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
           乱七八糟的一大堆,不用管,只要看清楚这里定义的函数就好了:

JNIEXPORT void JNICALL Java_Test_hello
  (JNIEnv *, jobject);
这个函数相当于就是Test类里的那个hello函数,将其用c/c++实现,Test类调用hello函数时调用的就是这些c/c++代码

所以,接下来就编写一个Test.c(cpp)文件,实现这个方法

#include "Test.h"
#include <cstdio>
JNIEXPORT void JNICALL Java_Test_hello
  (JNIEnv *, jobject){
  printf("Hello World\n");
  }
OK了。下面就要编译这个c/c++文件了,它的目标文件就是***.so(linux下的c/c++动态链接库,so是 shared object的缩写,共享库)

linux将c/c++源文件编译为.so文件的基本命令为

gcc -shared -fPIC -o ***.so ***.c

或 g++ -shared -fPIC -o ***.so ***.cpp

但是,因为这里有个特殊的头文件jni.h 所以直接这么弄肯定没法编译过(除非jni.h所在路径已经在环境变量里了),因此我们在编译的时候必须再增加参数,那就是关于jni需要用到的头文件所在的目录

linux下找到jni.h的方法是找到jdk的安装路径,/usr/lib/jvm 这个路径下就会有你安装的jdk,我装的是openjdk6,所以我的全部路径就是 /usr/lib/jvm/java-6-openjdk/include 以及/usr/lib/jvm/java-6-openjdk/include/linux

所以我的编译命令就是g++ -shared -fPIC -I/usr/lib/jvm/java-6-openjdk/include  -I/usr/lib/jvm/java-6-openjdk/include/linux -o Test.so Test.cpp

这样就能得到Test.so 这个共享库了,然后用 java Test 运行即可

这个时候可能会出错,因为Test在加载动态链接库的时候不知到它的路径,环境变量里有一个 LD_LIBRARY_PATH 只要将其复制为动态链接库所在路径即可(当然这么做的结果就是只能在当前shell中有效)

export   LD_LIBRARY_PATH = 动态链接库所在路径

java Test

屏幕上就会输出 hello了

…………………………………………………………

以上就是jni一个最简单的例子,能够用java调用c/c++代码了



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值