简体   繁体   English

Java 使用 JNA 调用 dll 错误:无效的内存访问

[英]Java use JNA call dll error:Invalid memory access

I want to call dll to write/read from hardware.However, I get the error below:我想调用 dll 来从硬件写入/读取。但是,我收到以下错误:

dll method: dll方法:

int NewKey(char *room,char *gate,char *stime,char *guestname,char *guestid, int  overflag, int Breakfast, long *cardno,char * track1,char * track2);

java method: java方法:

int NewKey(String room, String gate,String time,String guestname,String guestid, int overflag, int Breakfast, NativeLongByReference cardno, String track1, String track2);

The api document shows cardno as a out parameter and track1,track2 could be null. api文档显示cardno为out参数,track1,track2可以为null。

NativeLongByReference cardNo = new NativeLongByReference ();

int res = CLibrary.INSTANCE.NewKey("010001", "00", "201712021200201712031200", "Guest Name","Account No.", 0, 1, cardNo, null, null);

It don t work.它不起作用。 So I use a simple method:所以我使用了一个简单的方法:

dll method :

int EraseCard (long  cardno,char * track1,char * track2);

java method: java方法:

int EraseCard(NativeLong cardno, String  track1, String  track2); 

NativeLong a = new NativeLong(0L);

int res = CLibrary.INSTANCE.EraseCard (a, null, null);

It gets the same error again:它再次得到相同的错误:

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:383)
at com.sun.jna.Function.invoke(Function.java:315)
at com.sun.jna.Library$Handler.invoke(Library.java:212)
at A90PmsInterface.main(A90PmsInterface.java:104)

It seems like the error only occurs when I try to use the dll methods to read/write from/to hardware.似乎错误只发生在我尝试使用 dll 方法从/向硬件读/写时。

How can I solve the problem?我该如何解决问题?

details: win7 64 bite, jre1.8 32bite, jna4.1详细信息:win7 64 咬,jre1.8 32 咬,jna4.1

If you want to access memory from the dll, you will need to setup the proper data type needed to reference the memory location.如果要从 dll 访问内存,则需要设置引用内存位置所需的正确数据类型。 On pointer objects your jna should use ByteByReference for char* or you can also use PointerByReference instead of declaring the object as a String.在指针对象上,您的 jna 应该对 char* 使用 ByteByReference,或者您也可以使用 PointerByReference 而不是将对象声明为字符串。 Using PointerByReference will help you avoid memory leaks.使用 PointerByReference 将帮助您避免内存泄漏。

JNA Marshalling / Unmarshalling JNA 编组/解组

is a good place to start.是一个很好的起点。 Good Luck!祝你好运!

Edit: Java method declaration - (example of JNA XXByReference usage)编辑:Java 方法声明 -(JNA XXByReference 用法示例)

public int E1K_DI_Reads(int connection, byte channel, byte channelCount, IntByReference value);

Java usage - Java 用法 -

public int readDI(int connection, byte channel, byte count){
    IntByReference refValue = new IntByReference();
    lib.E1K_DI_Reads(connection, channel, count, refValue);
    int value = refValue.getValue();
    return value;
}

From your example:从你的例子:

int NewKey(PointerByReference room, PointerByReference gate,PointerByReference time,PointerByReference guestname,PointerByReference guestid, int overflag, int Breakfast, NativeLongByReference cardno, PointerByReference track1, PointerByReference track2);

You will have to adjust your methods code to get the actual pointers value.您将不得不调整您的方法代码以获得实际的指针值。

I guess the "MainDll" have multi dependencies.我猜“MainDll”有多个依赖项。

When I put all my needed dependcies dll under the project folder root path and use relative path to load my my dll, it finally successed.当我将所有需要的依赖项 dll 放在项目文件夹根路径下并使用相对路径加载我的 dll 时,它终于成功了。

    CLibrary INSTANCE = (CLibrary) Native.synchronizedLibrary((CLibrary) Native.loadLibrary("MainDll", CLibrary.class));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM