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

本文介绍了如何使用Java Native Access (JNA) 在Java中调用Linux下的C++动态库,包括简单调用、基本参数传递、模拟结构体传参(值传递和引用传递)以及回调Java方法的实现过程,详细展示了Java和C++代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记一次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下载到本地使用
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
            <version>5.2.0</version>
        </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 <iostream>

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

cpp文件 library.cpp

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

2、基本传参

实现步骤

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值