乐趣区

关于java:Java-调用自己封装的-jni-接口

介绍

JNI java native interface, jni 使 java 能够调用 c\c++ 编写的动态链接库。文章次要介绍演示如何编写几个简略的 jni 接口,java 间接调用,以及波及到的一些工具和配置。

环境

eclipse cpp
eclipse jee
centos 7

前提

g++ 编译 cpp 文件为动态链接库
gcc 编译 c 文件为动态链接库(略)
java 启动 jvm 时会加载动态链接库,以上编译后的链接库会放在 /lib/ 目录下,jvm 启动时会默认加载,查看会加载哪些目录的链接库,应用以下代码即可:System.out.println(System.getProperty("java.library.path"))

次要步骤为:

  • java 定义 jni 接口
  • javah 生成 c 的头文件
  • c \ c++ 实现 生成的头文件
  • gcc \ g++ 编译 c \ cpp 文件为动态链接库

配置

  • Location: /home/xxx/tmp/jdk1.8.0_301/bin/javah
  • Working Directory: ${project_loc}
  • Arguments: -classpath ${project_loc}/target/classes -d ${project_loc}/src/jni ${java_type_name}

  • 按图批改 refresh 配置

  • java 文件 JNI2.java

    package com.fei.code;
    
    public class JNI2 {public static native void print();
      public native void show();
      
      public native void showArgs(int i, String s, char[] c);
      
      public void run() {System.out.println("run hello ...");
      }
      
      public static void main(String[] args) {System.loadLibrary("myjni");
          // System.out.println(System.getProperty("java.library.path"));
          print();
          new JNI2().show();
          new JNI2().showArgs(1, "hello", new char[]{'a', 'b', 'c'});
      }
    }


点击图示按钮

生成文件 com_fei_code_JNI2.h

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

#ifndef _Included_com_fei_code_JNI2
#define _Included_com_fei_code_JNI2
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_fei_code_JNI2
 * Method:    print
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_fei_code_JNI2_print
  (JNIEnv *, jclass);

/*
 * Class:     com_fei_code_JNI2
 * Method:    show
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_fei_code_JNI2_show
  (JNIEnv *, jobject);

/*
 * Class:     com_fei_code_JNI2
 * Method:    showArgs
 * Signature: (ILjava/lang/String;[C)V
 */
JNIEXPORT void JNICALL Java_com_fei_code_JNI2_showArgs
  (JNIEnv *, jobject, jint, jstring, jcharArray);

#ifdef __cplusplus
}
#endif
#endif

编写 c++ 代码 com_fei_code_JNI2.cpp

#include "com_fei_code_JNI2.h"
#include <cstdio>
#include <iostream>
using namespace std;


/*
 * Class:     com_fei_code_JNI2
 * Method:    print
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_fei_code_JNI2_print
  (JNIEnv *, jclass)
{cout<<"Java_com_fei_code_JNI2_print"<<endl;}

JNIEXPORT void JNICALL Java_com_fei_code_JNI2_show
  (JNIEnv *env, jobject obj)
{jclass c = env->GetObjectClass(obj);
    jmethodID run = env->GetMethodID(c, "run", "()V");
    env->CallVoidMethod(obj, run);
    cout<<"Java_com_fei_code_JNI2_show"<<endl;
}

JNIEXPORT void JNICALL Java_com_fei_code_JNI2_showArgs
  (JNIEnv *, jobject, jint i, jstring s, jcharArray arr)

{cout<<"Java_com_fei_code_JNI2_show args:\t"<<i<<" "<<&s<<endl;}
sudo g++ \
-I /home/haoerfei/tmp/jdk1.8.0_301/include/ \
-I /home/haoerfei/tmp/jdk1.8.0_301/include/linux/ \
-shared -fpic -lm -ldl \
-o /lib/libmyjni.so \
/home/xxx/space/workspace/eclipse-jee/fei/src/jni/com_fei_code_JNI2.cpp 

运行 java main 办法 控制台会输入数据。

结语

调试过程中会呈现一些问题,比方找不到链接库等等,可查看门路或者 将 java 中的调用 jni 接口的办法正文运行一遍,再解除正文,保留再次运行。

以上就是本次阐明的代码,心愿能够帮忙到大家

退出移动版