2024-08-09 C语言Socket 把一个的结构体占用的字节值发到android java 里面,用jni的形式解析里面的变量,然后再把数据返回到java层

一、 c语言socket 把下面的结构体发到android java 里面,java如何很好的解析里面的变量呢?结构体内容如下:

struct image_header
{
	uint16_t width;
	uint16_t height;
	uint8_t  type;
	uint8_t  serial;
	uint16_t dummy;
	uint32_t len;
	uint16_t expo;
	uint16_t gain;
}__attribute__((packed)); 

二、用jni的形式解析里面的变量,然后再把数据返回到java层

        2.1 ImageHeader类

package com.example;

public class ImageHeader {
    private final int width;
    private final int height;
    private final int type;
    private final int serial;
    private final int dummy;
    private final long len;
    private final int expo;
    private final int gain;

    public ImageHeader(int width, int height, int type, int serial, int dummy, long len, int expo, int gain) {
        this.width = width;
        this.height = height;
        this.type = type;
        this.serial = serial;
        this.dummy = dummy;
        this.len = len;
        this.expo = expo;
        this.gain = gain;
    }

    // Getters
    public int getWidth() { return width; }
    public int getHeight() { return height; }
    public int getType() { return type; }
    public int getSerial() { return serial; }
    public int getDummy() { return dummy; }
    public long getLen() { return len; }
    public int getExpo() { return expo; }
    public int getGain() { return gain; }

    @Override
    public String toString() {
        return "ImageHeader{" +
                "width=" + width +
                ", height=" + height +
                ", type=" + type +
                ", serial=" + serial +
                ", dummy=" + dummy +
                ", len=" + len +
                ", expo=" + expo +
                ", gain=" + gain +
                '}';
    }
}

        2.2 jni 函数,确保 JNI 方法签名与 Java 构造函数匹配。

#include <jni.h>
#include <stdint.h>
#include <string.h>

// 定义结构体
struct image_header {
    uint16_t width;
    uint16_t height;
    uint8_t  type;
    uint8_t  serial;
    uint16_t dummy;
    uint32_t len;
    uint16_t expo;
    uint16_t gain;
} __attribute__((packed));

JNIEXPORT jobject JNICALL
Java_com_example_ImageHeaderReceiver_processImageHeader(JNIEnv *env, jobject thiz, jbyteArray headerData) {
    // 获取 byte 数组的指针
    jbyte *data = (*env)->GetByteArrayElements(env, headerData, NULL);
    if (data == NULL) {
        return NULL; // 出错处理
    }

    // 创建并填充结构体
    struct image_header header;
    memcpy(&header, data, sizeof(header));

    // 释放 byte 数组指针
    (*env)->ReleaseByteArrayElements(env, headerData, data, 0);

    // 获取 ImageHeader Java 类
    jclass headerClass = (*env)->FindClass(env, "com/example/ImageHeader");
    if (headerClass == NULL) {
        return NULL; // 错误处理
    }

    // 获取构造函数 ID
    jmethodID constructor = (*env)->GetMethodID(env, headerClass, "<init>", "(IIIIJIII)V");
    if (constructor == NULL) {
        return NULL; // 错误处理
    }

    // 创建 Java 对象
    jobject headerObject = (*env)->NewObject(env, headerClass, constructor,
                                             header.width, header.height,
                                             header.type, header.serial,
                                             header.dummy, (jlong)header.len,
                                             header.expo, header.gain);

    return headerObject;
}

        2.3 Java 代码调用 JNI 方法,在 Java 端调用 JNI 方法,并接收返回的 ImageHeader 对象。

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;

public class ImageHeaderReceiver {

    static {
        System.loadLibrary("native-lib"); // 加载 JNI 库
    }

    private native ImageHeader processImageHeader(byte[] headerData);

    public void receiveImageHeader(Socket socket) {
        try (DataInputStream dis = new DataInputStream(socket.getInputStream())) {
            byte[] headerData = new byte[16]; // 结构体大小
            dis.readFully(headerData);
            ImageHeader header = processImageHeader(headerData);
            if (header != null) {
                System.out.println(header);
            } else {
                System.out.println("Failed to process image header.");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

三、实际测试

3.1 jni部分

3.2 ImageHeader类

3.3 java 调用

3.4 运行结果如下,解析出来的数据跟我用另外一种方法解析出来的值是一样的,说明一切OK。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值