Java中传参并调用C++程序

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

2.视频:在Java中使用native方法调用C++代码_哔哩哔哩_bilibili

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
} private void closeCamera() { if (cameraCaptureSession != null) { cameraCaptureSession.close(); cameraCaptureSession = null; } if (cameraDevice != null) { cameraDevice.close(); cameraDevice = null; } 将 Java 的 `byte[]` 数组作为参数传递给 C++ 接口,并将其转换为 `char*` if (mediaRecorder != null) { mediaRecorder.release(); mediaRecorder = null; } } @Override ,可以使用 JNI 的 `GetByteArrayElements()` 函数获取 `byte[]` 数组数据,然后将其转换为 `char*`。 以下是一个示例代码: Java 代码: ```java public class MyClass { static { System.loadLibrary protected void onPause() { stopRecording(); closeCamera(); super.onPause(); } @Override protected void onResume("mylib"); } private native String processData(byte[] data); public static void main(String[] args) { MyClass() { super.onResume(); openCamera(); } } ``` 在这个Demo,我们使用了TextureView来显示 myClass = new MyClass(); byte[] data = "hello".getBytes(); String result = myClass.processData(data); System.out相机预览画面。当TextureView准备好后,我们调用openCamera()方法来打开相机。在.println(result); } } ``` C++ 代码: ```cpp JNIEXPORT jstring JNICALL Java_com_example_MyClass_processData(JNIEnvCameraDevice.StateCallback的onOpened()方法,我们获取到了CameraDevice实例后,我们调用createCameraPreview() *env, jobject obj, jbyteArray data) { jbyte* body = env->GetByteArrayElements(data, NULL); j方法来创建相机预览。在createCameraPreview()方法,我们首先创建一个SurfaceTexture,然后将它设置size length = env->GetArrayLength(data); char* cStr = new char[length + 1]; memcpy(cStr, body为TextureView的默认缓冲区大小。接下来,我们创建一个Surface,并将它添加到CaptureRequest.Builder。最后,我们调用cameraDevice.createCaptureSession()方法来创建CameraCaptureSession实例,并将这个Surface添加到会, length); cStr[length] = '\0'; // 这里可以调用 C++ 接口处理 cStr delete话。 当CameraCaptureSession创建成功后,我们调用updatePreview()方法来更新相机预览。在这个[] cStr; env->ReleaseByteArrayElements(data, body, JNI_ABORT); return env->NewStringUTF("result"); } ``方法,我们设置了CONTROL_MODE为CONTROL_MODE_AUTO,并将这个CaptureRequest添加到CameraCaptureSession。 当用户点击` 在 C++ ,使用 `GetByteArrayElements()` 函数获取 `byte[]` 数组数据,然后将其转换为 `char*`。在实际使用,可以将 `char*` 作为参数传递给 C++ 接口进行“抓拍”按钮时,我们调用captureStillImage()方法来进行拍照。在这个方法,我们首先处理。完成处理后,释放 `char*` 的内存,并将处理结果转换为 JNI 的 `jstring` 类型返回给 Java

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值