I'm developing something for a piece of hardware and I got a C library to communicate with the hardware. I have methods that send a signal to the hardware (like light bulb turn on) and those work fine on both C# and Java using JNA.
The machine also has a pressable button and when that button is pressed it will log a signal which can be retrieved with a method called A.
The way this was intended to work is to create a new thread which keeps calling this method until it returns 1 in which case it will have information regarding the button press.
I've got this working in C# with the following code:
while (true)
{
byte[] ccbdata = new byte[255];
short TagCommand = -1, nMsg_type = -1;
int ccblen = 0, nGwId = 0, nNode = 0;
int ret = CWrapper.Wrapper.A(ref nGwId, ref nNode, ref TagCommand, ref nMsg_type, ref ccbdata[0], ref ccblen);
if (ret > 0)
{
// do stuff
}
Thread.Sleep(100);
}
Where the method is imported in C# like:
[DllImport("Clibrary.dll")]
public static extern int C(ref int Gateway_ID, ref int Node_Addr, ref short Subcmd, ref short msg_type, ref byte data, ref int data_cnt);
I want this code also to work on Java. Unfortunately when I run this with java it never returns 1 unlike the C# implementation.
I was wondering if I am doing something wrong as I'm not experienced using JNA. In Java I import the method like this:
int C(LongByReference gatewayID, LongByReference tag_addr, LongByReference Subcmd, LongByReference msg_type,
ByteByReference data, LongByReference data_cnt);
And I try to run the code like this:
while(run) {
gatewayID.setValue(0);
tag_addr.setValue(0);
subcmd.setValue(-1);
msg_type.setValue(-1);
byte b = 0;
data.setValue(b);
data_cnt.setValue(0);
int ref = CWrapper.INSTANCE.C(gatewayID, tag_addr, subcmd, msg_type, data, data_cnt);
if (ref > 0) {
System.out.println("hit");
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
In the documentation I have about this method it is defined in C like:
C(ByRef gatewayID As Integer, ByRef tag_addr As Integer, ByRef subcmd As Integer, ByRef msg_type As Integer, ByRef data As Byte, ByRef data_cnt As Integer)
Does anyone know why the C# example works but not the Java one?
--EDIT 25-08-2021 12:04
The documentation says the parameters provided to the method are used. So I imagine if they are null somehow the method won't return anything. Perhaps the initialization is wrong for using the ByReference object?
--EDIT 26-08-2021
I've gotten the C++ signature which is:
typedef int (__stdcall *pC)(int& Gateway_ID, int& Node_Addr, short& Subcmd,
short& Msg_Type, unsigned char* Data, short& Data_Cnt);