问题
I want to call dll to write/read from hardware.However, I get the error below:
dll method:
int NewKey(char *room,char *gate,char *stime,char *guestname,char *guestid, int overflag, int Breakfast, long *cardno,char * track1,char * track2);
java method:
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.
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:
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.
How can I solve the problem?
details: win7 64 bite, jre1.8 32bite, jna4.1
回答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. On pointer objects your jna should use ByteByReference for char* or you can also use PointerByReference instead of declaring the object as a String. Using PointerByReference will help you avoid memory leaks.
JNA Marshalling / Unmarshalling
is a good place to start. Good Luck!
Edit: Java method declaration - (example of JNA XXByReference usage)
public int E1K_DI_Reads(int connection, byte channel, byte channelCount, IntByReference value);
Java usage -
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.
回答2:
I guess the "MainDll" have multi dependencies.
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.
CLibrary INSTANCE = (CLibrary) Native.synchronizedLibrary((CLibrary) Native.loadLibrary("MainDll", CLibrary.class));
来源:https://stackoverflow.com/questions/47625733/java-use-jna-call-dll-errorinvalid-memory-access