我正在使用Java(JNA)访问DLL代码。这是我正在使用的DLL:
U32 ReadMemU32(U32 Addr, U32 NumItems, U32* pData, U8* pStatus);
这是我的示例代码:
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.*;
import com.sun.jna.*;
import java.lang.*;
import java.util.*;
import com.sun.jna.*;
import java.lang.*;
public class DLL1 {
@UserFunction(Description="DLL1 Java wrapper", Name = "DLL1")
public static String DLL1(
@UserFunction.Arg(Name = "Address", Description = "Register Address")
String Address
) throws Exception {
byte Status[] = new byte[1];
PointerByReference Data = new PointerByReference ();
long Addr = Long.parseLong(Address.substring(2, Address.length()));
DllInterface.INSTANCE.ReadMemU32(Addr, 1, Data, Status);
System.out.println("Data = " + Data);
System.out.println("Data.getValue() = " + Data.getValue());
return null;
}
// C++ function definition and tell which DLL to fetch
public interface DllInterface extends Library {
DllInterface INSTANCE = (DllInterface) Native.loadLibrary("<dll name>", DllInterface.class);
long ReadMemU32(long Addr, long NumItems, PointerByReference pData, byte[] pStatus);
}
}
我得到的结果是:
Data = allocated@0xe25ac90 (8 bytes)(com.sun.jna.ptr.PointerByReference@e25ac90)
Data.getValue() = native@0xaaaaaaaa
结果(0xaaaaaaaa)与我期望的不匹配。
我是Java的新手,我不确定PointerByReference
是否适用于U32* pData
。请指教。
答案 0 :(得分:2)
看看函数的类型定义,我会做出有根据的猜测,并说pData
是函数将读取存储器写入的数组指针。您可以在此处直接使用int[]
。由于状态是通过指针作为out参数返回的,因此可以使用ByteByReference
。
在Java中,long
表示64位整数,等效于C ++的long long
。由于类型为U32
,因此可以安全地猜测它所引用的是32位整数。这将是int
。您可以检查JNA的类型映射here。
还请注意,由于该函数接受地址的32位整数,因此无法将64位地址传递给该函数。
我猜想此功能的一个正确映射是:
int ReadMemU32(
int address,
int numItems,
int[] pData,
ByteByReference status
);
如果您的函数确实只需要从内存中读取一个32位整数,则可以将pData
的类型更改为IntByReference
并以与status
相同的方式使用它参数的ByteByReference
。
由于该函数返回一个整数,所以我猜想它会返回读取的字节数。如果是这样,检查此值是否与期望的值匹配很重要。检查库的文档中有关返回值和错误状态的内容。
尝试一下:
import java.lang.*;
import java.util.*;
import com.sun.jna.*;
import com.sun.jna.ptr.*;
public class DLL1 {
@UserFunction(Description="DLL1 Java wrapper", Name = "DLL1")
public static String DLL1(
@UserFunction.Arg(Name = "Address", Description = "Register Address")
String Address
) throws Exception {
String addressWithoutPrefix = Address.substring(2)
int parsedAddress = Integer.parseInt(addressWithoutPrefix, 16)
int bytesToRead = 1;
int[] buffer = new int[bytesToRead];
ByteByReference status = new ByteByReference(0);
int BytesRead = DllInterface.INSTANCE.ReadMemU32(
parsedAddress,
bytesToRead,
buffer,
status
);
System.out.println("Status = " + status.getValue());
System.out.println("Bytes read = " + bytesRead);
System.out.println("Data = " + Arrays.toString(buffer));
return null;
}
// C++ function definition and tell which DLL to fetch
public interface DllInterface extends Library {
DllInterface INSTANCE = (DllInterface) Native.loadLibrary("<dll name>", DllInterface.class);
int ReadMemU32(
int address,
int numItems,
int[] pData,
ByteByReference status
);
}
}