java使用jna基于linux调用c++动态函数库(简单调用,基本传参数,模拟结构体传参(值&引用),回调java方法)

记一次jna调研成果,动机是公司开始做一个公安交通方面的项目,对接华为以及大华时,他们提供的sdk基本都是函数库,所以才有了这次“轰轰烈烈”的调研。
因为目前这方面的资料比较少,所以在调研过程中还是踩了不少坑,将这次成果记录下来,有需要的人可以借鉴一下,基本能满足需要

jna简述

JNA全称Java Native Access,是一个建立在经典的JNI技术之上的Java开源框架。
JNA提供工具用于调用c/c++动态函数库(如Window的dll以及linux的so)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标函数库的函数与结构,JNA将自动实现Java接口方法到函数的映射

jna&c++数据类型对照

java类型 c++类型 原生表现
boolean int 32位整数(可定制)
byte char 8位整数
char wchar_t 平台依赖
short short 16位整数
int int 32位整数(可定制)
long ong long, __int64 64位整数
float float 32位浮点数
double double 64位浮点数
Buffer/Pointer pointer 平台依赖(32或64位指针)
[] (基本类型的数组) pointer/array 2或64位指针(参数/返回值) 邻接内存(结构体成员)
String char* 0结束的数组 (native encoding or jna.encoding)
WString wchar_t* /0结束的数组(unicode)
String[] char** /0结束的数组的数组
WString[] wchar_t** /0结束的宽字符数组的数组
Structure struct*/struct 指向结构体的指针(参数或返回值) (或者明确指定是结构体指针)结构体(结构体的成员) (或者明确指定是结构体)
Union union 等同于结构体
Structure[] struct[] 结构体的数组,邻接内存
Callback (*fp)() Java函数指针或原生函数指针
NativeMapped varies 依赖于定义
NativeLong long 平台依赖(32或64位整数)
PointerType pointer 和Pointer相同

使用示例

环境说明:

  • jna-version:5.2.0
  • jdk-version:1.8
  • c++version:c++11
  • java开发使用idea
  • c++开发使用clion
  • g++版本自选
  • 下面是jna的maven坐标,也可以将jar下载到本地使用

        <dependency>
            <groupId>net.java.dev.jnagroupId>
            <artifactId>jnaartifactId>
            <version>5.2.0version>
        dependency>

1、简单调用

实现步骤

  • 创建一个接口TestNative继承Library
  • 创建一个本地方法(用native修饰的方法)cppHello()
  • 创建头文件 library.h,定义一个函数cppHello();
  • 创建cpp文件 library.cpp,实现头文件中的cppHello();
  • 执行命令生成liblibrary.so动态库
    g++ library.cpp -fPIC -shared -o liblibrary.so
  • 接口内用Native.load()方法加载函数库(使用绝对路径)创建一个TestNative实例
  • TestNative.testNative.cppHello();进行调用

java代码

import com.sun.jna.*;

import java.util.Arrays;
import java.util.List;

/**
 * @Author :feiyang
 * @Date :Created in 11:14 AM 2019/10/14
 */
public interface TestNative extends Library {
   
   TestNative testNative = Native.load("/Users/liblibrary.so", TestNative.class);
   /**
    * 
    * @author  feiyang
    * @return  void 
    * @date    2019/10/22
    * @throws
    */ 
   void cppHello();
   
   /**
     * 测试方法
     * @param args
     */
   static void main(String[] args) {
   
        TestNative.testNative.cppHello();
    }
   }

c++代码

头文件 library.h

#ifndef UNTITLED1_LIBRARY_H
#define UNTITLED1_LIBRARY_H

#include 

extern "C" {
   
    using namespace std;
    void cppHello();
};
#endif

cpp文件 library.cpp

#include "library.h"
#include 
extern "C" {
   
void cppHello() {
   
    using namespace std;
    cout << "cpp执行:cppHello!" << endl;
};
};

2、基本传参

实现步骤

你可能感兴趣的:(#,框架.java)