前沿
实际中,有时已经用C++写好的程序,需要在Java中调用。本文以加法(函数参数为二维整型数组)为例,说明了如何通过Java调用C++动态库。本文基于前面博客进行撰写,省略各种步骤,直接列出相应的代码。前文链接:https://blog.csdn.net/luzaijiaoxia0618/article/details/99685747.
代码点这里(https://github.com/luzaijiaoxia/jni-dll)下载。
C++工程代码
- 编写加法程序,头文件test.h代码如下
#include <vector>
#include <iostream>
using namespace std;
vector<vector<int>> test_func(vector<vector<int>> &variable1, vector<vector<int>> &variable2);
- 源文件test.cpp代码如下
#include"test.h"
vector<vector<int>> test_func(vector<vector<int>> &variable1, vector<vector<int>> &variable2) {
vector<vector<int>> sum(variable1.size());
for (int i = 0; i < variable1.size(); i++) {
for(int j=0;j<variable1[i].size();j++){
sum[i].push_back(variable1[i][j] + variable2[i][j]);
}
}
return sum;
}
- 在vs中,将此程序调通,主函数main.cpp代码如下:
#include "test.h";
#include <iostream>
using namespace std;
int main() {
vector<vector<int>> variable1 = { { 1,2,3 },{2,3,4} };
vector<vector<int>> variable2 = { { 4,5,6 } ,{5,6,7} };
vector<vector<int>> sum = test_func(variable1,variable2);
cout << "求和结果:" << endl;
for (int i = 0; i < sum.size(); i++) {
for (int j = 0; j < sum[i].size(); j++) {
std::cout << sum[i][j] << ' ';
}
std::cout << std::endl;
}
return 0;
}
注意:此代码非必须,只是为了验证C++代码正确。结果展示如下:
Java工程
-
新建Java工程:打开eclipse - File - New - Java Project;然后在新建的工程中,新建包和类,如下图:
-
在javaclass类中添加方法(即你以后要在Java中调用的函数),代码如下:
package java_dll;
public class javaclass {
public static native int[][] sum_func(int[][] var1,int[][] var2);
public static void main(String[] args) {
}
- 接着就是生成H文件等一系列操作,同本人以前的博客,链接在前沿已给出。
- 将生成的头文件加入C++工程,并编写其源文件函数,其代码如下(注意本文形参为int型,其他变量类型需进行修改,但是思路相同)
#include"java_dll_javaclass.h";
#include"test.h";
JNIEXPORT jobjectArray JNICALL Java_java_1dll_javaclass_sum_1func
(JNIEnv *env, jclass, jobjectArray var1_array, jobjectArray var2_array) {
//input
vector<vector<int>> var1;
int num1 = env->GetArrayLength(var1_array);
for (int i = 0; i < num1; i++) {
vector<int> c;
jintArray jc = jintArray(env->GetObjectArrayElement(var1_array, i));//取第i行
jint *jc_pointer = env->GetIntArrayElements(jc, NULL);
jint jc_len = env->GetArrayLength(jc);
for (int j = 0; j < jc_len; j++) {
c.push_back(jc_pointer[j]);
}
var1.push_back(c);
}
vector<vector<int>> var2;
int num2 = env->GetArrayLength(var1_array);
for (int i = 0; i < num2; i++) {
vector<int> c;
jintArray jc = jintArray(env->GetObjectArrayElement(var2_array, i));//取第i行
jint *jc_pointer = env->GetIntArrayElements(jc, NULL);
jint jc_len = env->GetArrayLength(jc);
for (int j = 0; j < jc_len; j++) {
c.push_back(jc_pointer[j]);
}
var2.push_back(c);
}
//output
vector<vector<int>> sum = test_func(var1, var2);
int X_len = sum.size();
int Y_len = sum[0].size();
jclass initClass = env->FindClass("[I");//找到一个Int类,如果是double则用[D
jobjectArray sum_return = env->NewObjectArray(X_len, initClass, NULL);
for (int i = 0; i < X_len; i++) {
jintArray output = env->NewIntArray(Y_len);//
jint *destArrayElems = env->GetIntArrayElements(output, NULL);
for (int j = 0; j < Y_len; j++) {
destArrayElems[j] = sum[i][j];
}
env->SetIntArrayRegion(output, 0, Y_len, destArrayElems);
env->SetObjectArrayElement(sum_return, i, output);
}
return sum_return;
}
- 然后就是生成dll动态库,步骤也与以前博客相同
测试
- Java工程调用代码如下:
package java_dll;
public class javaclass {
static {
System.loadLibrary("java_dll");
}
public static native int[][] sum_func(int[][] var1,int[][] var2);
public static void main(String[] args) {
int[][] var1 = { { 1,2,3 },{2,3,4} };
int[][] var2 = { { 4,5,6 } ,{5,6,7} };
System.out.println("input 1:");
for (int i = 0; i < var1.length; i++) {
for(int j=0;j<var1[i].length;j++) {
System.out.print(var1[i][j] + ", ");
}
System.out.println();
}
System.out.println();
System.out.println("input 2:");
for (int i = 0; i < var2.length; i++) {
for(int j=0;j<var2[i].length;j++) {
System.out.print(var2[i][j] + ", ");
}
System.out.println();
}
System.out.println();
int[][] sum;
sum= sum_func(var1,var2);
System.out.println("output:");
for (int i = 0; i < sum.length; i++) {
for(int j=0;j<sum[i].length;j++) {
System.out.print(sum[i][j] + ", ");
}
System.out.println();
}
System.out.println();
}
}
输出结果
本文到此就结束了,如有错误敬请谅解。