1.编好Java类
public class Test {
public native void test(String url);
}
2.编译Java头文件【javac -h . JavaClassName.java】
3.编译生成有Test.h、Test.class,复制Test.h,并将其中一个后缀名改为.cpp(C++源文件),如下图:
4.在VS中打开.cpp文件,引入三个基本的预编译头文件。
其中pch.h为VS生成.dll(动态链接库所需,否则运行会报错)、<jni.h>即为Java Native Interface,Java本地接口的头文件、Test.h为上面Test.java编译生成的头文件[告诉程序链接的相对位置,否则在java调用时中会报错。报错如下:
【java.lang.UnsatisfiedLinkError: 'void com.camunda.platform.Call.Call.test(java.lang.String)'】
5.若C++程序有其他需求,引用相应库以及编写代码,若有打印输出尽量少用中文,否则输出格式可能有误
提示:引用库方法:右击解决方案->属性,或者用同时按住快捷键Alt+Enter
Java中传参数给C++动态链接库
传参过程涉及两部分,Java->JNI,JNI->C++
以String类型为例:
1.Java->JNI
在Java中方法为:
public native void test(String url);
通过编译生成的Java.h,然后将Java.h变成JNI的方法变成:
JNIEXPORT void JNICALL Java_com_camunda_platform_Call_Call_test(JNIEnv* env, jobject, jstring url){};
2.JNI->C++
要想在C++程序中获取到数组类型的参数,需通过GetStringUTFChars()方法
JNIEXPORT void JNICALL Java_com_camunda_platform_Call_Call_test
(JNIEnv* env, jobject, jstring url) {
const char* Url = (env)->GetStringUTFChars(url, 0);
}
提示:
1.附上Java数据类型 VS JNI数据类型对应表
2.C++中所有代码
#include "pch.h"
//通常在Jdk安装目录的include文件夹内,D:\Program Files\Java\jdk-17\include
#include <jni.h>//JNI头文件
#include "com_camunda_platform_Call_Call.h"//编译生成的头文件
#include<stdio.h>
#include <iostream>
#include <shapefil.h>
//自己具体业务
int ma(const char * url) {
// 打开shapefile文件
SHPHandle shp = SHPOpen(url, "rb");
if (shp == nullptr) {
std::cout << "Failed to Open" << std::endl;
return 1;
}
// 获取shapefile的基本信息
int numEntities, shapeType;
double minBound[4], maxBound[4];
SHPGetInfo(shp, &numEntities, &shapeType, minBound, maxBound);
std::cout << "Entity_Number: " << numEntities << std::endl;
std::cout << "Geo_Type: " << shapeType << std::endl;
std::cout << "Min_Bou: " << minBound[0] << ", " << minBound[1] << std::endl;
std::cout << "Max_Bou: " << maxBound[0] << ", " << maxBound[1] << std::endl;
// 逐个读取实体
for (int i = 0; i < numEntities; i++) {
SHPObject* shape = SHPReadObject(shp, i);
// 处理实体的几何信息
for (int j = 0; j < shape->nVertices; j++) {
double x = shape->padfX[j];
double y = shape->padfY[j];
std::cout << "Point_Cor: " << x << ", " << y << std::endl;
}
// 释放实体内存
SHPDestroyObject(shape);
}
// 关闭shapefile文件
SHPClose(shp);
return 0;
}
JNIEXPORT void JNICALL Java_com_camunda_platform_Call_Call_test
(JNIEnv* env, jobject, jstring url) {
const char* Url = (env)->GetStringUTFChars(url, 0);//将JNI String转为C++中字符串
ma(Url);
};
附录:
1.资料:【🔍JNI中C++和Java的参数传递(JNI 参数传递】
Jni中C++和Java的参数传递 - 沉思的狗の博客 - BlogJava
https://www.cnblogs.com/zijianlu/archive/2012/11/01/2749390.html