尽管指定了正确的结构,为什么我会获得无效的内存访问?

时间:2015-11-10 09:38:18

标签: java c jna

我从Java调用C DLL方法。我用过JNA。但是当我调用该方法时,我得到以下异常。

Exception in thread "main" java.lang.Error: Invalid memory access
at com.sun.jna.Native.invokePointer(Native Method)
at com.sun.jna.Function.invokePointer(Function.java:470)
at com.sun.jna.Function.invoke(Function.java:415)
at com.sun.jna.Function.invoke(Function.java:315)
at com.sun.jna.Library$Handler.invoke(Library.java:212)
at com.sun.proxy.$Proxy0.start(Unknown Source)
at com.kube.rfid.RFIDMain.main(RFIDMain.java:31)

以下是我的C函数。

RFIDLIB_API ipj_error start(
    ipj_iri_device* iri_device       /*[in]*/,
    ipj_action      action           /*[in]*/)
{
    return ipj_start(iri_device, action);
}

以下是ipj_iri_device结构

typedef struct _ipj_iri_device
{
    IPJ_READER_CONTEXT    reader_context;
    IPJ_READER_IDENTIFIER reader_identifier;
    uint32_t              receive_timeout_ms;

    /* Internal Only */
    uint8_t               sync_state;
    bool                  wait_for_response;
    uint32_t              frame_length;
    uint32_t              receive_index;
    uint8_t               receive_buffer[IPJ_RECEIVE_BUFFER_SIZE];

#if !defined(IRI_RX_ONLY)
    uint8_t               transmit_buffer[IPJ_TRANSMIT_BUFFER_SIZE];
#endif

} ipj_iri_device;

以下是在C

中定义ipj_action的方法
typedef uint32_t ipj_action;

相关结构已在JAva中以下列方式定义。

public class ipj_iri_device extends Structure {

    private static final int IPJ_RECEIVE_BUFFER_SIZE = 1000;
    private static final int IPJ_TRANSMIT_BUFFER_SIZE = 1000;

    public Pointer reader_context;
    public Pointer reader_identifier;
    public int receive_timeout_ms;
    /* Internal Only */
    public byte sync_state;
    public byte wait_for_response;
    public int frame_length;
    public int receive_index;
    public byte[] receive_buffer = new byte[IPJ_RECEIVE_BUFFER_SIZE];
    public byte[] transmit_buffer = new byte[IPJ_TRANSMIT_BUFFER_SIZE];

    @Override
    protected List getFieldOrder() {
        return Arrays.asList("reader_context", "reader_identifier", "receive_timeout_ms", "sync_state","wait_for_response", "frame_length","receive_index","receive_buffer","transmit_buffer");
    }
}

主java类看起来像这样。

public class RFIDMain {

    public  rfidlib rlib;
    public  ipj_iri_device ipj_iri_device;
    public  ipj_action ipj_action;
    public  ipj_error errorStatus;
    public  ipj_connection_params connection_params;

    public static void main(String[] args) {

        //ByteBuffer iriDeviceBuffer = ByteBuffer.allocateDirect(1000);
        //ByteBuffer actionBuffer = ByteBuffer.allocateDirect(1000);
        //IntByReference value = new IntByReference();
        //int ipj_key = 0xD;// 0x1;
        //int ipj_connection_type = 0;

        RFIDMain r = new RFIDMain();

        PointerByReference pref = new PointerByReference();
        //Pointer ipj_reader_identifier = pref.getPointer();

        r.rlib = (rfidlib) Native.loadLibrary("rfidlib", rfidlib.class);
        r.ipj_iri_device = new ipj_iri_device();
        r.ipj_action = new ipj_action();
        r.errorStatus = r.rlib.start(r.ipj_iri_device, r.ipj_action);
    }

下面显示的是我在Java中的界面。

public interface rfidlib extends Library {

    public ipj_error initialize_iri_device(ipj_iri_device iriDevice);

    public ipj_error connect_device(ipj_iri_device iri_device, Pointer ipj_read_identifier, int ipj_connectionType,
        ipj_connection_params params);

    public ipj_error disconnect_device(ipj_iri_device iri_device);

    public ipj_error receive(ipj_iri_device iri_device);

    public ipj_error reset(ipj_iri_device iri_device, ipj_reset_type reset_type);

    public ipj_error set(ipj_iri_device iri_device, ipj_key key, int bank_index, int value_index, int value);

    public ipj_error set_value(ipj_iri_device iri_device, ipj_key key, int value);

    public ipj_error get(ipj_iri_device iri_device, ipj_key key, int bank_index, int value_index, IntByReference value);

    public ipj_error get_value(ipj_iri_device iri_device, ipj_key key, IntByReference value);

    public ipj_error start(ipj_iri_device iri_device, ipj_action action);

    public ipj_error stop(ipj_iri_device iri_device, ipj_action action);
}

为什么我会收到此异常?请指教。

1 个答案:

答案 0 :(得分:0)

您必须适当地实施结构的getFieldOrder()方法。它看起来应该类似于:

@Override
protected List getFieldOrder() {
    return Arrays.asList("reader_context", "reader_identifier", "receive_timeout_ms", ..... );
}

所有字段都必须按正确的顺序列出。此外,当前具有default可见性的所有字段都必须public

此外,您的主要java类RFIDMain不处于任何可能的状态。看起来你正试图在java程序上应用C ++语义 - 这是行不通的。一些提示:

  • 尽可能避免使用静态。而是创建局部变量或非静态成员。
  • 为您的会员提供适当的知名度。默认情况通常不是您想要的。
  • 没有RAII!通过声明变量,它们用null初始化。您必须显式调用构造函数以使用对象初始化变量。
  • 您有许多未使用的变量。你初始化它们,但你没有使用它们 - 它们不会在合适的位置神奇地使用它们。务必在需要的地方使用它们!