编译包使用C库导致JVM崩溃 [英] Pragma Pack used C library causing the jvm to crash

查看:270
本文介绍了编译包使用C库导致JVM崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用JNA使用的C库在我的Java code。我的这些C结构,其成员,我需要在Java中进行打印。由于内存对齐和填充的大小从我其实期望不同。因此,我用杂包,这是结构如何看待像现在。

I used a C library in my Java code using JNA. I have these C structures of whose members I need to print in Java. Because of the memory alignment and padding the size was differing from what I was actually expecting. Therefore I used pragma pack and this is how the structures look like now.

#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) )

PACK(
typedef struct 
{
    size_t size;
    uint8_t bytes[48];
} ipj_tid_t);


PACK(
typedef struct 
{
    bool has_epc; //1
    ipj_epc_t epc; //64+8
    bool has_tid; //1
    ipj_tid_t tid; //48+8
    bool has_pc; //1
    uint32_t pc; //4
    bool has_xpc; //1
    uint32_t xpc; //4
    bool has_crc; //1
    uint32_t crc; //4
    bool has_timestamp; //1
    uint64_t timestamp; //8
    bool has_rssi; //1
    int32_t rssi; //4
    bool has_phase; //1
    int32_t phase; //4
    bool has_channel; //1
    uint32_t channel; //4
    bool has_antenna; //1
    uint32_t antenna; //4
} ipj_tag); //total size= 174


PACK(
typedef struct 
{
    bool has_error;
    ipj_error error;
    bool has_test_id;
    uint32_t test_id;
    bool has_result_1;
    uint32_t result_1;
    bool has_result_2;
    uint32_t result_2;
    bool has_result_3;
    uint32_t result_3;
    size_t data_count;
    uint32_t data[16];
    bool has_timestamp;
    uint64_t timestamp;
    size_t lt_buffer_count;
    uint32_t lt_buffer[21];
} ipj_test_report);


PACK(
typedef struct
{
    size_t size;
    uint8_t bytes[64];
} ipj_tag_operation_data_t);


PACK(
typedef  struct
{
    bool has_error;  //1
    ipj_error error; //4
    bool has_tag; //1
    ipj_tag tag; //174
    bool has_tag_operation_type; //1
    ipj_tag_operation_type tag_operation_type; //4
    bool has_tag_operation_data; //1
    ipj_tag_operation_data_t tag_operation_data; //72
    bool has_retries; //1
    uint32_t retries; //4
    bool has_diagnostic; //1
    uint32_t diagnostic; //4
    bool has_timestamp; //1
    uint64_t timestamp; //8
    size_t lt_buffer_count; //8
    uint32_t lt_buffer[30]; //120
} ipj_tag_operation_report); //405

当我从Visual Studio运行code,我没有得到它从任何错误,异常或崩溃。但是,当我把这种从Java中,JVM崩溃。这究竟是为什么?有在C code等结构过于而不是包​​装。难道是理由吗?请指点。

When I run the code from Visual Studio, I am not getting any errors, exceptions or crashes from it. But when I call this from Java, the jvm is crashing. Why is this happening? There are other structures in the C code too which are not packed. Could it be a reason? Please advice.

我在上面已经显示在C.使用从C code返回什么结构是所有的处理后,这种结构。

The structures I have shown above are used in C. What is returned from the C code is this structure after all the processing.

#define RX_MAX_SIZE     405
#pragma pack(push, 1)
typedef struct _report
{
    ipj_report_id report_id;
    uint32_t data_size;
    uint32_t data[RX_MAX_SIZE];
 } report;
 #pragma pack(pop)

这已被使用的等效JNA结构如下

The equivalent JNA structure that has been used is as follows.

public class _report extends Structure {

    public static class ByValue extends _report implements Structure.ByValue {

    }

    public _report() {
        super();
        setAlignType(ALIGN_NONE);
    }

    public _ipj_report_id reportid;
    public int data_size;
    public int[] data = new int[405]; 

    @Override
    protected List getFieldOrder() {
        return Arrays.asList("reportid", "data_size", "data");
    }

}

public class _ipj_report_id extends Structure {

    public int ipj_report_id;

    public _ipj_report_id() {
        super();
        setAlignType(ALIGN_NONE);
    }

    @Override
    protected List getFieldOrder() {
        return Arrays.asList("ipj_report_id");
    }

}

下面是结构调试JNA code时,我得到。

Below is the structure I get when debugging the JNA code.

    _report$ByValue(auto-allocated@0x18918cc0 (1628 bytes)) {
   _ipj_report_id reportid@0=_ipj_report_id(allocated@0x18918cc0 (4 bytes) (shared from auto-allocated@0x18918cc0 (1628 bytes))) {
    int ipj_report_id@0=0
   }
   int data_size@4=195
   int data[405]@8=[I@78bb0ecb
 }

下面是我如何调用JNA此方法。

Below is how I call this method in JNA.

 rfidlib rlib = (rfidlib) Native.loadLibrary("rfidlib", rfidlib.class);
_report.ByValue report = new _report.ByValue();
 report = rlib.get_next_reports();


推荐答案

JNA假定(在这种情况下,MS编译器)为当前的目标平台默认结构布局。

JNA assumes default structure layout for the current target platform (in this case, the MS compiler).

您可以通过调用 Structure.toString()与调用JVM后 -Djna.dump_memory打印JNA生成的内存布局的布局= TRUE

You can print the layout of the JNA-generated memory layout by calling Structure.toString() after invoking the JVM with -Djna.dump_memory=true.

您可以再比较与JNA产生的实际布局所需的结构布局,寻找差异。如果您一般用布尔在Java结构,默认是分配一个本地 INT ,因此,如果这不是同样大小的原生布尔,你需要要么使用字节在Java端或明确提供一个 TypeMapper 你的结构来表示布尔应该被转换成一个大小与本机兼容布尔(注意,本机布尔的大小不是由C标准定义)。

You can then compare your desired structure layout with the actual layout generated by JNA to look for differences. If you generically use boolean in your Java structure, the default is to allocate a native int, so if that's not the same size as your native bool, you need to either use byte on the Java side or explicitly supply a TypeMapper to your Structure to indicate that boolean should be converted to a size compatible with native bool (note that the size of native bool is not defined by the C standard).

我推荐的的使用的#pragma包在code,除非你明确地需要它。

I would recommend not using #pragma pack in your code unless you explicitly need it.

请与您的Java 结构实施和调试输出更新你的问题。

Please update your question with your Java Structure implementation and its debug output.

这篇关于编译包使用C库导致JVM崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆