android jni 中jstring字符串的转化 和 一些常用数据转化

本文详细介绍如何在JNI层将jstring转换为C/C++字符串,包括constchar*和char*类型转换方法,以及如何从Java层传递字符串、ByteBuffer到C++进行相机数据处理,涉及yuv数据获取和释放内存等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、jni层,jstring转化为const char *

const char *tablePath = (env->GetStringUTFChars(tablePath_, 0));

2、jni层 jstring 转化为 char *

char *tablePath = const_cast<char *>(env->GetStringUTFChars(tablePath_, 0));

3、jni 函数中,将字符串string转化未 c++ 字符串string

方法1

std::string getString(JNIEnv *env , jstring jstring1 )
{
    const char *path =NULL;
    path = env->GetStringUTFChars(jstring1, 0);
    std::string spFn(path);
    env->ReleaseStringUTFChars(jstring1, path);
    return spFn;
}

 

方法2

    const char *tablePath = (env->GetStringUTFChars(tablePath_, 0));
    pTable = string(tablePath);
    env->ReleaseStringUTFChars(tablePath_, tablePath);

注意:释放掉 jni层获得java层string的开销

4 jni 相机数据yuv的获取,ByteBuffer 在c++中获得byte的数组指针

java层:

 private ImageReader.OnImageAvailableListener onImageAvailableListener = new ImageReader.OnImageAvailableListener() {
        @Override
        public void onImageAvailable(ImageReader reader) {
        
            Image mImage = reader.acquireLatestImage();
            if(mImage == null)
                return;

                Image.Plane[] planes = mImage.getPlanes();

        ByteBuffer Camera_y = planes[0].getBuffer();
        ByteBuffer Camera_u = planes[1].getBuffer();
        ByteBuffer Camera_v = planes[1].getBuffer();
 cameraData(planes[0].getBuffer(),planes[0].getRowStride() ,planes[0].getPixelStride(),
                        planes[1].getBuffer(),planes[1].getRowStride() ,planes[1].getPixelStride(),
                        planes[2].getBuffer(),planes[2].getRowStride() ,planes[2].getPixelStride(),
                        w,h , tablePath,1f , imageType);


}

}

public static native void cameraData(ByteBuffer Camera_y, int rowStride_y, int pixStride_y,
                                                       ByteBuffer Camera_u, int rowStride_u, int pixStride_u,
                                                       ByteBuffer Camera_v, int rowStride_v, int pixStride_v,
                                                       int width, int height , String tablePath , float progress ,int ImageType);


//Camera_y 、u 、v 是ByteBuffer
Java_com_example_lammy_Camera_cameraData(
        JNIEnv *env, jclass type, jobject Camera_y, jint rowStride_y, jint pixStride_y,
        jobject Camera_u, jint rowStride_u, jint pixStride_u, jobject Camera_v, jint rowStride_v,
        jint pixStride_v, jint width, jint height, jstring tablePath_ , jfloat progress ,jint imageType) {
    char *tablePath = const_cast<char *>(env->GetStringUTFChars(tablePath_, 0));

    jbyte *dataY = (jbyte *) env->GetDirectBufferAddress(Camera_y);
    jbyte *dataU = (jbyte *) env->GetDirectBufferAddress(Camera_u);
    jbyte *dataV = (jbyte *) env->GetDirectBufferAddress(Camera_v);
    unsigned char *y = (unsigned char *) dataY;
    unsigned char *u = (unsigned char *) dataU;
    unsigned char *v = (unsigned char *) dataV;
    ...
}

当然也可以直接传入byte数组,在java层获得,但效率相对低。

java

 byte []buffer_y = new byte[planes[0].getBuffer().remaining()];
                planes[0].getBuffer().get(buffer_y);
                byte []buffer_u = new byte[planes[1].getBuffer().remaining()];
                planes[1].getBuffer().get(buffer_u);
                byte []buffer_v = new byte[planes[2].getBuffer().remaining()];
                planes[2].getBuffer().get(buffer_v);
jbyteArray buffer_y;
jbyte *dataY2 = env->GetByteArrayElements(buffer_y , false);

 

### Android 开发中 JNI 数据处理 在 Android 应用程序开发过程中,JNI (Java Native Interface) 提供了一种机制使得 Java 代码可以调用 C/C++ 编写的函数并访问这些本地方法。对于数据处理而言,主要涉及如何通过 JNI 进行参数传递以及返回值获取。 #### 参数传递与基本类型转换 当从 Java 层面调用本地方法时,可以通过定义带有 `native` 关键字的方法实现跨语言交互。例如,在 Java 中声明如下: ```java public native int add(int a, int b); ``` 此操作会告知 JVM 此方法将在外部库中找到其具体实现[^2]。接着,在 C 或者 C++ 文件里编写对应的逻辑来完成加法运算,并将结果作为整数形式传回给 Java 调用方[^1]。 #### 复杂对象的数据交换 除了简单的数值外,还可以利用指针指向结构体的方式来进行更复杂的信息传输。比如字符串类型的变量会被映射成 jstring 类型;数组则对应于 jobjectArray 等等。下面是一个例子展示了怎样把一个 String 数组从 Java 发送到 C 函数中去: ```c++ JNIEXPORT void JNICALL Java_com_example_myapp_MyClass_printStrings(JNIEnv *env, jobject obj, jobjectArray strings){ jint length = env->GetArrayLength(strings); // 获取数组长度 for(jint i=0; i<length ;i++){ jstring str = static_cast<jstring>(env->GetObjectArrayElement(strings,i)); const char* cstr = env->GetStringUTFChars(str,NULL); printf("%s\n",cstr); env->ReleaseStringUTFChars(str,cstr); } } ``` 这段代码首先获得了输入的对象数组大小,之后遍历每一个元素将其转化为标准C风格的字符序列打印出来。最后记得释放掉之前分配的空间以防止内存泄漏[^3]。 #### 错误处理及异常传播 值得注意的是,在进行 JNI 编程的时候还需要考虑可能出现的各种错误情况。如果遇到未预期的情况应该及时抛出合适的异常让上层能够捕获到并作出相应反应。这通常涉及到使用像 ThrowNew 方法这样的工具向 Java 报告问题所在[^4]。 ```cpp if(error_occurred()){ jclass exCls = env->FindClass("com/example/myapp/MyException"); if(exCls != NULL){ env->ThrowNew(exCls,"An error occurred while processing data."); } } ``` 以上便是有关 Android 平台上基于 JNI 的一些基础数据处理技巧介绍。希望可以帮助开发者更好地理解两者之间的协作方式及其应用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值