Cmake编译so库 ,JNA执行so
项目结构如图
头文件
#include <stdio.h>
#include <stdio.h>
int add(int a,int b);
int multiply(int a,int b);
int minus(int a,int b);
int divide(int a,int b);
实现文件
#include "c_fun.h"
#include <jni.h>
#include <stdio.h>
// cc -c fun_main.c => fun_main.o
// 将.o 文件 => *.so
// cc -shared -o libCFun.so c_fun.o
// nm libCfun.so nm命令查看so文件里的方法声明
int add(int a,int b){
return a + b;
}
int multiply(int a,int b){
return a * b;
}
int minus(int a,int b){
return a - b;
}
int divide(int a,int b){
if(b == 0 ){
return -1;
}
return a / b;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.18)
set(CMAKE_CXX_STANDARD 11)
#aux_source_directory(. src )
#aux_source_directory(. include )
project(CFun) # 项目名称
set(LINK_JNI_DIR /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/include )
set(LINK_JMI_DIR /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/include/darwin )
# 收集c/c++文件并赋值给变量SRC_LIST_CPP ${PROJECT_SOURCE_DIR}代表区当前项目录
file(GLOB SRC_LIST_CPP ${PROJECT_SOURCE_DIR}/src/*.cpp)
file(GLOB SRC_LIST_C ${PROJECT_SOURCE_DIR}/src/*.c)
# 指定头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# 包含第三方头文件,这里包含jni.h、jni_md.h头文件路径
include_directories(${LINK_JNI_DIR} ${LINK_JMI_DIR})
#打印
#message ("${PROJECT_SOURCE_DIR}")
# 指定生成库文件的目录
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
link_directories(${LINK_JNI_DIR} ${LINK_JMI_DIR})
find_library(${PROJECT_SOURCE_DIR}/include ${LINK_JNI_DIR} ${LINK_JMI_DIR})
# 取变量SRC_LIST_CPP 与 SRC_LIST_C的值
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
# SHARED => 为.dylib文件
#add_library(CFun SHARED ${SRC_LIST_CPP} ${SRC_LIST_C} ${LINK_JNI_DIR} ${LINK_JMI_DIR} )
# MODULE => 为.so文件
add_library(CFun MODULE ${SRC_LIST_CPP} ${SRC_LIST_C} ${LINK_JNI_DIR} ${LINK_JMI_DIR} )
# STATIC => 为.a文件
#add_library(CFun STATIC ${SRC_LIST_CPP} ${SRC_LIST_C} ${LINK_JNI_DIR} ${LINK_JMI_DIR})
- 在c_fun目录执行命令:
$root> mkdir build && cd build && cmake .. && make
然后得到libCFun.so文件,存放目录在c_fun/lib下
Java JNA调用该so动态库
- 添加依赖jar
<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.3.1</version> </dependency>
JnaLibrary.java => 申明接口与so对应关系
import com.sun.jna.Library;
import com.sun.jna.Native;
public interface JnaLibrary extends Library {
JnaLibrary INSTANCE = Native.load("/Users/iriszhang/Documents/java_workspace/JNADemo/c_fun/lib/libCfun.so", JnaLibrary.class);
int add(int a,int b);
int multiply(int a,int b);
int minus(int a,int b);
int divide(int a,int b);
String getSalt();
}
JNAMain.java
public class JnaMain {
public static void main(String args[]){
int a = 200,b=100;
int add = JnaLibrary.INSTANCE.add(a, b);
int multiply = JnaLibrary.INSTANCE.multiply(a, b);
int minus = JnaLibrary.INSTANCE.minus(a, b);
int divide = JnaLibrary.INSTANCE.divide(a, b);
// out: 200
System.out.println(add);
// out: 20000
System.out.println(multiply);
// out: 100
System.out.println(minus);
// out: 2
System.out.println(divide);
}
}