我正在为一块硬件开发一些东西,并且我有一个 C 库来与硬件通信。我有向硬件发送信号的方法(比如打开灯泡),并且使用 JNA 在 C# 和 Java 上都可以正常工作。
该机器还有一个可按下的按钮,当按下该按钮时,它将记录一个信号,该信号可以通过称为 A 的方法检索。
预期的工作方式是创建一个新线程,该线程一直调用此方法,直到它返回 1 在这种情况下,它将获得有关按钮按下的信息。
我已经使用以下代码在 C# 中工作:
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);
}
在 C# 中导入该方法的位置,例如:
[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);
我希望这段代码也能在 Java 上工作。不幸的是,当我使用 java 运行它时,它永远不会返回 1,这与 C# 实现不同。
我想知道我是否做错了什么,因为我没有使用 JNA 的经验。在Java中,我导入这样的方法:
int C(LongByReference gatewayID, LongByReference tag_addr, LongByReference Subcmd, LongByReference msg_type,
ByteByReference data, LongByReference data_cnt);
我尝试像这样运行代码:
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();
}
}
在我拥有的有关此方法的文档中,它在 C 中定义,例如:
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)
有谁知道为什么 C# 示例有效但 Java 示例无效?
--编辑 25-08-2021 12:04
文档说使用了提供给该方法的参数。所以我想如果它们以某种方式为空,该方法将不会返回任何东西。也许使用 ByReference 对象的初始化是错误的?
--编辑 26-08-2021
我得到了 C++ 签名,它是:
typedef int (__stdcall *pC)(int& Gateway_ID, int& Node_Addr, short& Subcmd,
short& Msg_Type, unsigned char* Data, short& Data_Cnt);