Java Native Access code Error: “Invalid memory access”

为君一笑 提交于 2020-01-06 05:28:07

问题


I have access to test.h and test.so files:

test.h

int insert_data(void *location_data, uint64_t device_id, uint64_t event_id,
                uint64_t motion_seq, uint64_t utc_time, uint32_t sensor_seq,
                uint32_t device_seq, uint32_t tick_mark, uint16_t ble,
                int movement, int path_id);

I am now writing JNA code to call the above method.

interface TestCLibrary extends Library {
    TestCLibrary INSTANCE = (TestCLibrary) Native.loadLibrary(“test”, TestCLibrary);

    int insert_data(Pointer test_data, long device_id, long event_id,
                    long motion_seq, long utc_time, int sensor_seq,
                    int device_seq, int tick_mark, short ble,
                    int movement, int path_id);
 }

public class JNATest {
    public static void main(String[] args) throws IOException{ 
        Native.setProtected(true); 
        int path_id = 1, movement = 1, tick_mark = 1, device_seq = 1;
        long utc_time = System.currentTimeMillis();
        int sensor_seq = 100;
        short ble = 25;
        long motion_seq = 22222299;
        long device_id = 111122333;
        long event_id = 44445555;  

        Pointer test_data = Pointer.NULL; 

        TestCLibrary.INSTANCE.insert_data(test_data, device_id, event_id, motion_seq, utc_time, sensor_seq, device_seq, tick_mark, ble, movement, path_id);
   }
}

While running the JNATest facing following exception at this code location:

TestCLibrary.INSTANCE.insert_data

Exception in thread "main" java.lang.Error: Invalid memory access at com.sun.jna.Native.invokeInt(Native Method) at com.sun.jna.Function.invoke(Function.java:419) at com.sun.jna.Function.invoke(Function.java:354) at com.sun.jna.Library$Handler.invoke(Library.java:244) at com.test.apps.$Proxy0.insert_data(Unknown Source) ....

How to avoid such error ? and how can I initialize a Pointer in JNA with default value ?


回答1:


The error is happening because, I assume, the function writes the data into the memory pointed at by the pointer passed to it. You need to allocate memory to which the function can write. It cannot write to a NULL pointer.

What you should do depends on what the data is, how it is structured, and how you're using it.

If the data is just an array of integers or bytes, treat it as such (change array size accordingly):

int insert_data(int[] data, // ... etc.
// ...

int[] data = new int[4096];
insert_data(data, /* ... */

However, if you know that the data produced by the function is a struct or class, create a Java class for it. JNA will automagically "marshal" the data written by the native function into meaningful Java class instances:

  • https://java-native-access.github.io/jna/4.2.1/com/sun/jna/Structure.html

  • https://github.com/java-native-access/jna/blob/master/www/StructuresAndUnions.md

Since the function accepts a pointer, you'll want to use Structure.ByReference:

int insert_data(Structure.ByReference data, // ...



回答2:


The JVM Crash problem was solved after I performed following steps:

1) Native.setProtected(true);

2) Free up memory using Native library Native.free(Pointer.nativeValue(my_pointer_by_ref.getValue()));

3) running the program with following CLI options - -XX:-UseLoopPredicate -DLD_PRELOAD=/usr/lib/jvm/java-8-oracle/jre/lib/amd64/libjsig.so



来源:https://stackoverflow.com/questions/45383453/java-native-access-code-error-invalid-memory-access

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!