一、 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。