最近研究如何封装c++给java使用,通过调研发现swig工具能很好的实现次功能。因此把本次研究的整个流程记录下来,以供大家借鉴使用。
本次实验的整个文件结构如下所示
xx@ubuntu:~/xx/swigtest$ tree .
.
├── com
│ └── test
│ ├── DoubleVector.class
│ ├── IntVector.class
│ ├── StrVector.class
│ ├── test.class
│ └── testJNI.class
├── demo.class
├── demo.java
├── libtest.so
├── temp
│ ├── DoubleVector.java
│ ├── IntVector.java
│ ├── StrVector.java
│ ├── test.java
│ └── testJNI.java
├── test.cpp
├── test.h
├── test.i
├── test.jar
├── test.o
├── test_wrap.cxx
└── test_wrap.o
3 directories, 20 files
sudo apt-get install swig
$ javac
The program 'javac' can be found in the following packages:
* openjdk-6-jdk
* ecj
* gcj-4.4-jdk
* gcj-4.6-jdk
* gcj-4.5-jdk
* openjdk-7-jdk
输入
sudo apt install openjdk-7-jdk
验证是否安装成功:
javac --version
新建swigtest文件夹,并在文件夹下新建test.h、test.cpp、test.i文件。同时新建temp文件夹、com/test文件夹
#include
#include
int add(int a,int b);
std::string getString();
void setString(std::string str);
void setStrings(std::vector<std::string>& strList);
#include "test.h"
int add(int a, int b)
{
return a+b;
}
std::string getString()
{
return "Hello world!";
}
void setString(std::string str)
{
}
void setStrings(std::vector<std::string>& strList)
{
}
%module test
%{
#include "test.h"
%}
%include "std_string.i"
%include "std_vector.i"
%include "test.h"
namespace std{
%template(StrVector) vector<string>;
%template(IntVector) vector<int>;
%template(DoubleVector) vector<double>;
}
swig3.0 -c++ -java -package com.test -outdir ./temp -o test_wrap.cpp ./test.i
命令解释:
-package 指定生成java文件的包名称
-outdir 指定生成java文件路径
-o 指定生成的c++对外接口文件
javac ./temp/*.java
mv ./temp/*.class ./com/test
4.封装成jar包
jar -cvf test.jar ./com
至此jar包已经封装成功。接下来封装.so包
gcc -c -fPIC test.cpp test_wrap.cpp -I/usr/lib/jvm/jdk-14.0.1/include -I/usr/lib/jvm/jdk-14.0.1/include/linux
注意:因为test_wrap.cpp中需要用到jni.h和jin_md.h,所以需要把其对应的路径包含进来。我的为安装jdk后的路径:
/usr/lib/jvm/jdk-14.0.1/include
/usr/lib/jvm/jdk-14.0.1/include/linux
gcc -shared -o libtest.so test.o test_wrap.o
import com.test.*;
class demo{
static {
//System.load("/home/weibaox/xwb/swigtest/libtest.so");
System.loadLibrary("test"); //刚才生成的libtest.so动态库。
}
public static void main(String argv[]){
int i = test.add(1,2);
System.out.println(i);
System.out.println(test.getString());
StrVector strvector;
test.setStrings(strvector);
}
}
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
3.编译demo.java文件
javac -cp ./test.jar demo.java
-cp 指定demo.java依赖的jar包
4.执行生成的demo
java demo