You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JNA封装LibRaw时raw_image指针始终为空的技术求助

解决LibRaw JNA封装中raw_image指针为空的问题

1. 严格匹配结构体字段顺序与类型

C结构体的字段顺序、类型必须和JNA的Structure完全对齐,包括你省略的Other members。字段偏移错误会导致读取不到正确的指针值。

修正后的结构体示例:

public class LibRaw_data extends Structure {
    public Pointer image; // 对应C的ushort (*image)[4]
    public LibRaw_image_sizes sizes; // 必须声明该结构体,不能省略
    // 按C头文件顺序补上所有libraw_data_t的其他成员
    public LibRaw_rawdata rawdata;
    public Pointer parent_class;

    // 强制指定字段顺序,避免JNA按字段名自动排序导致错误
    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("image", "sizes", /* 其他成员 */, "rawdata", "parent_class");
    }
}

public class LibRaw_rawdata extends Structure {
    public Pointer raw_alloc;
    public Pointer raw_image; // 对应C的ushort* raw_image
    public Pointer color4_image; // 对应C的ushort (*color4_image)[4]
    public Pointer color3_image; // 对应C的ushort (*color3_image)[3]
    // 按C头文件顺序补上所有libraw_rawdata_t的其他成员

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("raw_alloc", "raw_image", "color4_image", "color3_image", /* 其他成员 */);
    }
}

2. 手动同步结构体内存(核心解决步骤)

本地函数(如libraw_unpack)修改结构体内存后,JNA不会自动同步到Java对象字段,必须手动调用read()刷新:

retCode = LibRaw.INSTANCE.libraw_unpack(librawdata);
// 同步主结构体内存
librawdata.read();
// 同步嵌套的rawdata结构体内存
librawdata.rawdata.read();

if (librawdata.rawdata.raw_image != null) {
    // 注意raw_image是ushort数组,用getShortArray()而非getByteArray()
    int imageSize = librawdata.sizes.raw_width * librawdata.sizes.raw_height;
    short[] rawPixelData = librawdata.rawdata.raw_image.getShortArray(0, imageSize);
}

3. 修正函数声明与使用逻辑

  • libraw_raw2image()声明缺少参数,C API需要传入libraw_data_t*,正确声明:

    int libraw_raw2image(LibRaw_data lr);
    

    如果流程需要调用该函数生成图像数据,需在libraw_unpack后调用,并再次同步内存。

  • 主代码无需提前new LibRaw_data(),直接使用libraw_init的返回值:

    LibRaw.LibRaw_data librawdata = LibRaw.INSTANCE.libraw_init(0);
    retCode = LibRaw.INSTANCE.libraw_open_file(librawdata, fname);
    retCode = LibRaw.INSTANCE.libraw_unpack(librawdata);
    // 同步内存
    librawdata.read();
    librawdata.rawdata.read();
    

4. 避免PointerByReference的误用

raw_image是C中的ushort*,直接用Pointer即可;PointerByReference用于传递指针的指针(如ushort**),此处完全不需要。

内容的提问来源于stack exchange,提问作者Marek P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:26:11