JAVA调用C/C++动态库(JNI)

JNI是java自带的功能,引用也非常简单 System.loadLibrary("libjni");
JNI和JNA不同,JNI的用法比JNA更复杂。libjni的C++动态库有很多坑需要避免。
首先就是java和C++程序是相互关联的,两者无法完全分离开来。
如果你在java项目中写C++对应的方法名。如下,写sig类里包含的方法:

package src.sig;

public class sig {
    public  native long importPkey(String str);
    public  native String newPkey();
    public  native String GetBase58(long pkey);
    public  native String GetPubStr(long pkey);
}

写完之后则需要生成对应的sig.h文件,需要到项目的对应目录下,如上的src.sig则到src的同级目录下,打开命令行,输入javac -h . sig.java就会在同级目录下生成src_sig_sig.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class src_sig_sig */

#ifndef _Included_src_sig_sig
#define _Included_src_sig_sig
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     src_sig_sig
 * Method:    importPkey
 * Signature: (Ljava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_src_sig_sig_importPkey
  (JNIEnv *, jobject, jstring);

/*
 * Class:     src_sig_sig
 * Method:    newPkey
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_src_sig_sig_newPkey
  (JNIEnv *, jobject);

/*
 * Class:     src_sig_sig
 * Method:    GetBase58
 * Signature: (J)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_src_sig_sig_GetBase58
  (JNIEnv *, jobject, jlong);

/*
 * Class:     src_sig_sig
 * Method:    GetPubStr
 * Signature: (J)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_src_sig_sig_GetPubStr
  (JNIEnv *, jobject, jlong);

#ifdef __cplusplus
}
#endif
#endif

生成文件之后,拷贝到C程序对应的目录下。对应的还需要,修改src_sig_sig.cpp文件的方法名(和.h方法名相同)。

#include "src_sig_sig.h"
#include "debug.h"
#include "jni.h"
#include "sig.h"
#include "base64.h"
#include 
#include "jni_tools.h"
#include "sigTx.h"

/*
 * Class:     src_sig_sig
 * Method:    importPkey
 * Signature: (Ljava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_src_sig_sig_importPkey
  (JNIEnv * env, jobject, jstring str){
     ......//方法实现
  }

/*
 * Class:     src_sig_sig
 * Method:    newPkey
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_src_sig_sig_newPkey
  (JNIEnv *env , jobject){
  		......
  }

  JNIEXPORT jstring JNICALL Java_src_sig_sig_GetBase58
  (JNIEnv *env , jobject, jlong pkey){
      	......
  }

  JNIEXPORT jstring JNICALL Java_src_sig_sig_GetPubStr
  (JNIEnv *env, jobject, jlong pkey){
     ......
  }

写完之后,进行C++代码编译。
windows平台需要编译成.dll的库,打开VS的控制台,进入到对应的build目录下cd build,如果目录下有文件则需要删除,没有则接下来cmake .. -G "MinGW Makefiles", # .为当前目录, “MinGW Makefiles"为makefile类型,如果编译器为vs的话使用"NMake Makefiles”`

如果有其他引用库则需要先cmake ..完成之后,输入mingw32-make编译获得最终编译好的.dll文件。
.dll文件复制到C:\Windows\System32目录下,或者直接在环境变量path中配置对应的.dll路径目录,涉及到其他库也放在对应目录下。

JAVA调用C/C++动态库(JNI)_第1张图片

这样整个部署流程就完毕了。

接下来就是简单的调用:在调用前请关闭idea(所有项目)再重新打开项目,让库重新加载。
java里直接调用对应的方法

 public static void main(String[] arg) throws IOException {
   System.loadLibrary("libjni");
   String NewPkey="1234" ;
   sig sig_obj=new sig();
   long pkey1=sig_obj.importPkey(NewPkey);
 	System.out.println(pkey1);
 }

如果没有报错,有输出值则说明jni调用成功!

你可能感兴趣的:(java,java,c++,c语言)