Java 调用c函数复制结构后JNR-FFI崩溃

Java 调用c函数复制结构后JNR-FFI崩溃,java,c,ffi,jnr,Java,C,Ffi,Jnr,我正在尝试使用与C库接口。 第一个函数调用zbc_open工作并返回指向打开设备的指针。然后下一次调用zbc_get_device_info会导致JVM崩溃 原因是什么?如何解决? 我认为错误在zbc的接口或我传递的参数中的某个地方,但是在google中搜索JNR的任何文档都没有得到任何有用的结果。如果我省略结构中的数组部分,也会发生崩溃 我使用的项目作为起点,因为我的目标是编写一个FUSE文件系统 C职能: C结构zbc_设备_信息: JNR接口: 主要功能: JVM崩溃: Struct的声明

我正在尝试使用与C库接口。 第一个函数调用zbc_open工作并返回指向打开设备的指针。然后下一次调用zbc_get_device_info会导致JVM崩溃

原因是什么?如何解决? 我认为错误在zbc的接口或我传递的参数中的某个地方,但是在google中搜索JNR的任何文档都没有得到任何有用的结果。如果我省略结构中的数组部分,也会发生崩溃

我使用的项目作为起点,因为我的目标是编写一个FUSE文件系统

C职能:

C结构zbc_设备_信息:

JNR接口:

主要功能:

JVM崩溃:


Struct的声明不正确。未声明字段。尝试使用以下声明:

package com.github.goto1134.libzbc;

import jnr.ffi.Runtime;
import jnr.ffi.Struct;
import jnr.ffi.util.EnumMapper.IntegerEnum;

public class zbc_device_info
        extends Struct {
    public static final int ZBC_DEVICE_INFO_LENGTH = 32;


    public final Enum<zbc_dev_type> zbd_type = new Enum<>(zbc_dev_type.class);
    public final Enum<zbc_dev_model> zbd_model = new Enum<>(zbc_dev_model.class);
    public final UTF8String zbd_vendor_id = new UTF8String(ZBC_DEVICE_INFO_LENGTH);
    public final Unsigned32 zbd_flags = new Unsigned32();
    public final Unsigned64 zbd_sectors = new Unsigned64();
    public final Unsigned32 zbd_lblock_size = new Unsigned32();
    public final Unsigned64 zbd_lblocks = new Unsigned64();
    public final Unsigned32 zbd_pblock_size = new Unsigned32();
    public final Unsigned64 zbd_pblocks = new Unsigned64();
    public final Unsigned64 zbd_max_rw_sectors = new Unsigned64();
    public final Unsigned32 zbd_opt_nr_open_seq_pref = new Unsigned32();
    public final Unsigned32 zbd_opt_nr_non_seq_write_seq_pref = new Unsigned32();
    public final Unsigned32 zbd_max_nr_open_seq_req = new Unsigned32();


    protected zbc_device_info(Runtime runtime) {
        super(runtime);
    }

    public enum zbc_dev_type
            implements IntegerEnum {

        /**
         * Unknown drive type.
         */
        ZBC_DT_UNKNOWN(0x00),

        /**
         * Zoned block device (for kernels supporting ZBC/ZAC).
         */
        ZBC_DT_BLOCK(0x01),

        /**
         * SCSI device.
         */
        ZBC_DT_SCSI(0x02),

        /**
         * ATA device.
         */
        ZBC_DT_ATA(0x03),

        /**
         * Fake device (emulation mode).
         */
        ZBC_DT_FAKE(0x04);

        private final int value;

        zbc_dev_type(int value) {

            this.value = value;
        }

        @Override
        public int intValue() {
            return value;
        }
    }

    public enum zbc_dev_model
            implements IntegerEnum {

        /**
         * Unknown drive model.
         */
        ZBC_DM_DRIVE_UNKNOWN(0x00),

        /**
         * Host-aware drive model: the device type/signature is 0x00
         * and the ZONED field of the block device characteristics VPD
         * page B1h is 01b.
         */
        ZBC_DM_HOST_AWARE(0x01),

        /**
         * Host-managed drive model: the device type/signature is 0x14/0xabcd.
         */
        ZBC_DM_HOST_MANAGED(0x02),

        /**
         * Drive-managed drive model: the device type/signature is 0x00
         * and the ZONED field of the block device characteristics VPD
         * page B1h is 10b.
         */
        ZBC_DM_DEVICE_MANAGED(0x03),

        /**
         * Standard block device: the device type/signature is 0x00
         * and the ZONED field of the block device characteristics VPD
         * page B1h is 00b.
         */
        ZBC_DM_STANDARD(0x04);

        private final int value;

        zbc_dev_model(int value) {

            this.value = value;
        }

        @Override
        public int intValue() {
            return value;
        }
    }
}

在hs日志中,有一个调用堆栈导致程序崩溃。你能提供吗?

看起来很有效。非常感谢你。是否有一些文档可以让我学习如何正确使用这个接口?不幸的是,除了javadoc之外,没有其他文档。
enum zbc_dev_type   zbd_type
enum zbc_dev_model  zbd_model
char    zbd_vendor_id [ZBC_DEVICE_INFO_LENGTH]
uint32_t    zbd_flags
uint64_t    zbd_sectors
uint32_t    zbd_lblock_size
uint64_t    zbd_lblocks
uint32_t    zbd_pblock_size
uint64_t    zbd_pblocks
uint64_t    zbd_max_rw_sectors
uint32_t    zbd_opt_nr_open_seq_pref
uint32_t    zbd_opt_nr_non_seq_write_seq_pref
uint32_t    zbd_max_nr_open_seq_req
public interface zbc{
        public void zbc_set_log_level(String level);
        public int zbc_open(String filename,int flags, PointerByReference p);
        public void zbc_get_device_info(Pointer dev,zbc_device_info info);
    }

public static class zbc_device_info extends Struct {
    int zbd_type;
    int zbd_model;
    byte zbd_vendor_id[]=new byte[32];
    u_int32_t zbd_flags;
    u_int64_t zbd_sectors;
    u_int32_t zbd_lblock_size;
    u_int64_t zbd_lblocks;
    u_int32_t zbd_pblock_size;
    u_int64_t zbd_pblocks;
    u_int64_t zbd_max_rw_sectors;
    u_int32_t zbd_opt_nr_open_seq_pref;
    u_int32_t zbd_opt_nr_non_seq_write_seq_pref;
    u_int32_t zbd_max_nr_open_seq_pref;

    protected zbc_device_info(Runtime runtime) {
        super(runtime);

    }

}
public static void main(String[] args) {
    zbc z = LibraryLoader.create(zbc.class).load("zbc");
    Runtime runtime=Runtime.getRuntime(z);

    z.zbc_set_log_level("debug");
    PointerByReference pr = new PointerByReference();
    int ret=z.zbc_open("/temp/test.img", IO_RDWR,pr);
    zbc_device_info info=new zbc_device_info(runtime);

    z.zbc_get_device_info(pr.getValue(),info);
}
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007fa794300c70, pid=29106, tid=0x00007fa7bd4a4700
#
# JRE version: OpenJDK Runtime Environment (8.0_131-b11) (build 1.8.0_131-8u131-b11-2ubuntu1.16.04.3-b11)
# Java VM: OpenJDK 64-Bit Server VM (25.131-b11 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [jffi6917022509387828651.so+0x5c70]  jffi_releaseArrays+0x60
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/mmmm/jnr-fuse/hs_err_pid29106.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
package com.github.goto1134.libzbc;

import jnr.ffi.Runtime;
import jnr.ffi.Struct;
import jnr.ffi.util.EnumMapper.IntegerEnum;

public class zbc_device_info
        extends Struct {
    public static final int ZBC_DEVICE_INFO_LENGTH = 32;


    public final Enum<zbc_dev_type> zbd_type = new Enum<>(zbc_dev_type.class);
    public final Enum<zbc_dev_model> zbd_model = new Enum<>(zbc_dev_model.class);
    public final UTF8String zbd_vendor_id = new UTF8String(ZBC_DEVICE_INFO_LENGTH);
    public final Unsigned32 zbd_flags = new Unsigned32();
    public final Unsigned64 zbd_sectors = new Unsigned64();
    public final Unsigned32 zbd_lblock_size = new Unsigned32();
    public final Unsigned64 zbd_lblocks = new Unsigned64();
    public final Unsigned32 zbd_pblock_size = new Unsigned32();
    public final Unsigned64 zbd_pblocks = new Unsigned64();
    public final Unsigned64 zbd_max_rw_sectors = new Unsigned64();
    public final Unsigned32 zbd_opt_nr_open_seq_pref = new Unsigned32();
    public final Unsigned32 zbd_opt_nr_non_seq_write_seq_pref = new Unsigned32();
    public final Unsigned32 zbd_max_nr_open_seq_req = new Unsigned32();


    protected zbc_device_info(Runtime runtime) {
        super(runtime);
    }

    public enum zbc_dev_type
            implements IntegerEnum {

        /**
         * Unknown drive type.
         */
        ZBC_DT_UNKNOWN(0x00),

        /**
         * Zoned block device (for kernels supporting ZBC/ZAC).
         */
        ZBC_DT_BLOCK(0x01),

        /**
         * SCSI device.
         */
        ZBC_DT_SCSI(0x02),

        /**
         * ATA device.
         */
        ZBC_DT_ATA(0x03),

        /**
         * Fake device (emulation mode).
         */
        ZBC_DT_FAKE(0x04);

        private final int value;

        zbc_dev_type(int value) {

            this.value = value;
        }

        @Override
        public int intValue() {
            return value;
        }
    }

    public enum zbc_dev_model
            implements IntegerEnum {

        /**
         * Unknown drive model.
         */
        ZBC_DM_DRIVE_UNKNOWN(0x00),

        /**
         * Host-aware drive model: the device type/signature is 0x00
         * and the ZONED field of the block device characteristics VPD
         * page B1h is 01b.
         */
        ZBC_DM_HOST_AWARE(0x01),

        /**
         * Host-managed drive model: the device type/signature is 0x14/0xabcd.
         */
        ZBC_DM_HOST_MANAGED(0x02),

        /**
         * Drive-managed drive model: the device type/signature is 0x00
         * and the ZONED field of the block device characteristics VPD
         * page B1h is 10b.
         */
        ZBC_DM_DEVICE_MANAGED(0x03),

        /**
         * Standard block device: the device type/signature is 0x00
         * and the ZONED field of the block device characteristics VPD
         * page B1h is 00b.
         */
        ZBC_DM_STANDARD(0x04);

        private final int value;

        zbc_dev_model(int value) {

            this.value = value;
        }

        @Override
        public int intValue() {
            return value;
        }
    }
}