Java调用C++共享库

在实际项目开发中,有时会遇到需要在Java中去调用C++实现的功能的场景。本文介绍一种实现方式。

总体思路

Java调用C++有多种方式,其中之一是利用Java的jna包去调用C++的共享库。实现需要以下几步:

一个示例

以下通过一个简单的例子描述实现的过程。

首先,用C++实现两个简单的函数:

1
2
3
4
5
6
7
8
9
10
#include <iostream>

extern "C" {
int add(int a, int b) {
return a + b;
}
void print(char* str) {
std::cout << str << std::endl;
}
}

此处,C++代码最好采用C的规则编译,用C++的规则会导致符号表发生一些变化,导致Java无法调用。当然,解决的办法也有,但是比较麻烦,还是不推荐使用。

通过g++将刚才写的源代码编译为共享库 libjnatest.so:

1
g++ -fPIC -shared -o libjnatest.so jnatest.cpp

至此,C++这一侧的工作就完成了,接下来是Java。

在Java代码中要引入jna包,并且定义出和C++中暴露的接口一致的接口,关于数据类型的映射关系在后文中给出:

1
2
3
4
5
6
7
8
9
10
11
12
import com.sun.jna.Library;
import com.sun.jna.Native;

public interface JnaTest extends Library {
public static final String JNA_ImgProcess = "jnatest";
public static final JnaTest instance =
(JnaTest)Native.loadLibrary(JnaTest.JNA_ImgProcess,JnaTest.class);

int add(int a, int b);
void print(String str);

}

最后,在Java中使用以上的接口:

1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
JnaTest instance = JnaTest.instance;
int result = instance.add(3,6);
instance.print("abcd");
System.out.println(result);
}
}

运行的时候需要将共享库jnatest.so置于系统的环境变量下,让系统能够搜索到这个库。

Java与C++的数据类型映射关系

Native Type Size Java Type
char 8-bit integer byte
short 16-bit integer short
wchar_t 16/32-bit character char
int 32-bit integer int
bool boolean value boolean
long 32/64-bit integer NativeLong
long long 64-bit integer long
float 32-bit FP float
double 64-bit FP double
char* C string String
void* pointer Pointer

参考

https://www.cnblogs.com/bigben0123/articles/11084523.html