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

JNA调用Native函数无法获取嵌套结构数据求助

问题诊断与解决方法

核心问题分析

你的代码存在三个关键问题,导致file.src始终为null:

  1. 文件名缺少null终止符:C语言的char*字符串必须以\0结尾,你用ByteBuffer传递路径时只写入了路径字节,没有添加终止符,Native函数无法正确识别文件名,导致文件加载失败。
  2. 结构参数传递方式错误:Native函数要求传入MyLoadFile*(结构指针),你直接传递MyLoadFile实例时,JNA默认按值传递(ByValue),而非引用传递,Native函数无法修改你创建的Java结构对象。
  3. 未同步Native内存到Java对象:即使Native函数修改了结构内存,JNA不会自动将更新同步到Java对象,需要手动调用read()方法刷新数据。

分步解决

1. 修正文件名传递

直接使用String传递文件名,JNA会自动处理char*的转换和null终止符,比手动操作ByteBuffer更可靠:

String fName = "D:/test/file";

2. 调整JNA函数定义

将第二个参数改为MyLoadFile.ByReference,明确告诉JNA传递结构的指针:

int LoadFile(String fname, MyLoadFile.ByReference logfile, int reset);

3. 修正调用逻辑

实例化MyLoadFile.ByReference,调用函数后手动调用read()同步内存:

MyLoadFile.ByReference file = new MyLoadFile.ByReference();
int retCode = MyLibrary.LoadFile("D:/test/file", file, 0);
System.out.println("Ret code: " + retCode);
// 同步Native修改后的内存到Java对象
file.read();
// 现在可以访问file.src
if (file.src != null) {
    // 若需要访问Src的内容,同样要调用src.read()
    file.src.read();
    // 比如获取FileId:
    String fileId = file.src.FileId.getString(0);
    System.out.println("FileId: " + fileId);
}

4. 额外注意事项

  • 如果你坚持使用ByteBuffer传递文件名,必须手动添加null终止符:
    byte[] bytes = "D:/test/file\0".getBytes(StandardCharsets.US_ASCII);
    ByteBuffer fName = ByteBuffer.allocateDirect(bytes.length);
    fName.put(bytes);
    fName.flip();
    
  • 对于嵌套的Src结构,当file.src不为null时,需要调用file.src.read()才能获取其内部字段的值,因为Src.ByReference本质是指针,JNA不会自动读取指向的内存内容。

完整修正后的代码示例

JNA函数接口

int LoadFile(String fname, MyLoadFile.ByReference logfile, int reset);

调用代码

MyLoadFile.ByReference file = new MyLoadFile.ByReference();
int retCode = MyLibrary.LoadFile("D:/test/file", file, 0);
System.out.println("Ret code: " + retCode);

// 同步结构数据
file.read();

if (file.src != null) {
    file.src.read();
    // 读取FileId
    String fileId = file.src.FileId.getString(0);
    System.out.println("FileId: " + fileId);
    // 读取Version数组
    for (int i = 0; i < file.src.Version.length; i++) {
        System.out.println("Version[" + i + "]: " + file.src.Version[i].longValue());
    }
}

内容的提问来源于stack exchange,提问作者Andrey Vladimirovich

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 22:33:18