linux环境jni demo

原文链接:http://www.happycxz.com/m/?p=373

step 1 准备接口文件

先弄个java文件 Hi.java:

(我是把要测试的代码顺便也写好了,main不是必须的)

public class Hi {
    static {
            System.loadLibrary("Hi");
    }
    //声明的本地方法
    public  static native void Fun1(String strName);
    public  static native String Fun2(String strName);
    public static void main(String[] args) {
        Fun1("boy");
        System.out.println(Fun2("girl") + ", print in JAVA.");
    }
}

step 2 编译class

javac Hi.java

生成 Hi.class

step 3 生成 Hi.h 头文件

javah -classpath . Hi

生成 Hi.h 。内容如下,不需要修改:

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

#ifndef _Included_Hi
#define _Included_Hi
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Hi
 * Method:    Fun1
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_Hi_Fun1
  (JNIEnv *, jclass, jstring);

/*
 * Class:     Hi
 * Method:    Fun2
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_Hi_Fun2
  (JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

step 4 实现 Hi.c 对应功能

关于java的变量和c变量的对接使用规则,自行查百度。

#include "Hi.h"
#include <stdio.h>

//与Hi.h中函数声明相同

JNIEXPORT void JNICALL Java_Hi_Fun1  (JNIEnv * env, jclass arg, jstring instring)
{
    //从instring字符串取得指向字符串UTF编码的指针
    const jbyte *str = (const jbyte *)env->GetStringUTFChars( instring, JNI_FALSE );
    printf("[Fun1]Hello, olami, I'm %s, print in C.\n",str);
    //通知虚拟机本地代码不再需要通过str访问Java字符串。
    env->ReleaseStringUTFChars( instring, (const char *)str );
    return;
}

JNIEXPORT jstring JNICALL Java_Hi_Fun2  (JNIEnv * env, jclass arg, jstring instring)
{
    char tmpstr[100];
    const jbyte *str = (const jbyte *)env->GetStringUTFChars( instring, JNI_FALSE );
    sprintf(tmpstr, "[Fun2]Hello, olami, I'm %s",str);
    env->ReleaseStringUTFChars( instring, (const char *)str );
    return env->NewStringUTF(tmpstr);
}

step 5 编译 Hi.c

依赖jdk中两个文件: jni.h 和 jni_md.h ;因为这两个文件在我试验机器上的两个目录,所以下述命令里需要有两个 -I 参数来指定 include 路径。

找不到这两个文件?? 可能你的机器上装的只有JRE,装一下JDK就能找到了。

g++ -I /usr/lib/jvm/java-8-openjdk-armhf/include/linux/ -I /usr/lib/jvm/java-8-openjdk-armhf/include/ -fPIC -shared -o libHi.so Hi.c

上述命令会生成 libHi.so

step 6 将libHi.so移到java.library.path中

windows环境中,会默认先找当前路径,所以不需要这一步。

linux环境下,使用libHi.so,有以下三种方式:

方式一

用java代码打印出 System.getProperty(“java.library.path”) 路径,然后把 libHi.so 拷到任意一个路径中。

方式二

添加环境变量 LD_LIBRARY_PATH ,将当前目录加到变量中:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
方式三

直接运行时带参数,如:

java -Djava.library.path=.  -cp . Hi

step 7 运行体验

使用上一步中的方式三,直接运行即可看到效果。

附全程主要操作日志:

pi@bpi-iot-ros-ai:~/jni/demo$ ll
total 16
drwxrwxr-x 2 pi pi 4096 May 23 17:29 ./
drwxrwxr-x 3 pi pi 4096 May 23 17:06 ../
-rw-rw-r-- 1 pi pi  871 May 23 17:28 Hi.c
-rw-rw-r-- 1 pi pi  348 May 23 17:28 Hi.java
pi@bpi-iot-ros-ai:~/jni/demo$ javac Hi.java 
pi@bpi-iot-ros-ai:~/jni/demo$ 
pi@bpi-iot-ros-ai:~/jni/demo$ ll
total 20
drwxrwxr-x 2 pi pi 4096 May 23 17:30 ./
drwxrwxr-x 3 pi pi 4096 May 23 17:06 ../
-rw-rw-r-- 1 pi pi  871 May 23 17:28 Hi.c
-rw-rw-r-- 1 pi pi  785 May 23 17:30 Hi.class
-rw-rw-r-- 1 pi pi  348 May 23 17:28 Hi.java
pi@bpi-iot-ros-ai:~/jni/demo$ javah -classpath . Hi
pi@bpi-iot-ros-ai:~/jni/demo$ ll
total 24
drwxrwxr-x 2 pi pi 4096 May 23 17:30 ./
drwxrwxr-x 3 pi pi 4096 May 23 17:06 ../
-rw-rw-r-- 1 pi pi  871 May 23 17:28 Hi.c
-rw-rw-r-- 1 pi pi  785 May 23 17:30 Hi.class
-rw-rw-r-- 1 pi pi  528 May 23 17:30 Hi.h
-rw-rw-r-- 1 pi pi  348 May 23 17:28 Hi.java
pi@bpi-iot-ros-ai:~/jni/demo$ g++ -I /usr/lib/jvm/java-8-openjdk-armhf/include/linux/ -I /usr/lib/jvm/java-8-openjdk-armhf/include/ -fPIC -shared -o libHi.so Hi.c
pi@bpi-iot-ros-ai:~/jni/demo$ ll
total 36
drwxrwxr-x 2 pi pi 4096 May 23 17:30 ./
drwxrwxr-x 3 pi pi 4096 May 23 17:06 ../
-rw-rw-r-- 1 pi pi  871 May 23 17:28 Hi.c
-rw-rw-r-- 1 pi pi  785 May 23 17:30 Hi.class
-rw-rw-r-- 1 pi pi  528 May 23 17:30 Hi.h
-rw-rw-r-- 1 pi pi  348 May 23 17:28 Hi.java
-rwxrwxr-x 1 pi pi 8312 May 23 17:30 libHi.so*
pi@bpi-iot-ros-ai:~/jni/demo$ java -Djava.library.path=.  -cp . Hi
[Fun1]Hello, olami, I'm boy, print in C.
[Fun2]Hello, olami, I'm girl, print in JAVA.
pi@bpi-iot-ros-ai:~/jni/demo$ 
pi@bpi-iot-ros-ai:~/jni/demo$
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当您在Java程序中需要调用C/C++代码时,可以使用Java Native Interface(JNI)来实现。下面是一个简单的JNI示例,演示了如何将Java方法与C函数相互调用: 1. 创建一个Java类,例如"JNIDemo.java",其中包含您想要调用的本地方法: ```java public class JNIDemo { // 本地方法声明 public native void sayHello(); // 加载本地库 static { System.loadLibrary("jni_demo"); // 加载名为"jni_demo"的本地库 } // 测试 public static void main(String[] args) { JNIDemo demo = new JNIDemo(); demo.sayHello(); // 调用本地方法 } } ``` 2. 在命令行中使用`javac`编译Java类:`javac JNIDemo.java`。 3. 生成C头文件,可以使用`javah`工具:`javah JNIDemo`。这将生成名为"JNIDemo.h"的头文件。 4. 创建一个C源文件,例如"jni_demo.c",实现您在Java中声明的本地方法: ```c #include <stdio.h> #include "JNIDemo.h" JNIEXPORT void JNICALL Java_JNIDemo_sayHello(JNIEnv *env, jobject obj) { printf("Hello from C!\n"); } ``` 5. 在命令行中使用C编译器编译C源文件,并生成共享库文件(DLL或SO): - 对于Windows(使用MinGW):`gcc -shared -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" jni_demo.c -o jni_demo.dll` - 对于Linux/Mac:`gcc -shared -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" jni_demo.c -o libjni_demo.so` 注意:请将`$JAVA_HOME`替换为您Java安装的实际路径。 6. 运行Java程序:`java JNIDemo`。您将看到输出:"Hello from C!"。 这是一个简单的JNI示例,演示了如何在Java和C之间进行方法调用。您可以根据自己的需求扩展和定制此示例。希望对您有帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值