Java在使用JNA调用dll函数时崩溃
我正在使用JNA运行dll函数: 以下是与该方式对应的所有代码: 本机声明:Java在使用JNA调用dll函数时崩溃,dll,java-7,jna,javaw,Dll,Java 7,Jna,Javaw,我正在使用JNA运行dll函数: 以下是与该方式对应的所有代码: 本机声明: //how the method declared H264_Login (char *sIP, unsigned short wPort, char *sUserName, char *sPassword, LP_DEVICEINFO lpDeviceInfo, int *error, ,SocketStyle socketTyle=TCPSOCKET); // where LP_DEVICEINFO is a s
//how the method declared
H264_Login (char *sIP, unsigned short wPort, char *sUserName, char *sPassword, LP_DEVICEINFO lpDeviceInfo, int *error, ,SocketStyle socketTyle=TCPSOCKET); // where LP_DEVICEINFO is a struct
//how the struct declared
typedef struct _H264_DVR_DEVICEINFO
{
SDK_SYSTEM_TIME tmBuildTime; // the "SDK_SYSTEM_TIME" is another struct
char sSerialNumber[64];
int byChanNum;
unsigned int uiDeviceRunTime;
SDK_DeviceType deviceTye; // the "SDK_DeviceType" is a enum
}H264_DVR_DEVICEINFO,*LP_DEVICEINFO;
// this is how "SDK_SYSTEM_TIME" is defined
typedef struct SDK_SYSTEM_TIME{
int year;
int month;
int day;
}SDK_SYSTEM_TIME;
// this is how "SDK_DeviceType" is defined
enum SDK_DeviceType
{
SDK_DEVICE_TYPE_DVR,
SDK_DEVICE_TYPE_MVR,
SDK_DEVICE_TYPE_NR
};
// this is how "SocketStyle" is defined
enum SocketStyle
{
TCPSOCKET=0,
UDPSOCKET,
SOCKETNR
};
以下是它们相应的Java映射:
public class Test implements StdCallLibrary {
public interface simpleDLL extends StdCallLibrary {
long H264_Login(String sIP, short wPort, String sUserName, String sPassword,
Structure DeviceDate, int error, int TCPSOCKET);
}
static
{
System.loadLibrary("NetSdk");
}
// the struct implementation
public static class DeviceDate extends Structure{
public SDK_SYSTEM_TIME tmBuildTime;
public String sSerialNumber;
public IntByReference byChanNum;
public IntByReference uiDeviceRunTime;
public IntByReference deviceTpye;
@Override
protected List<Object> getFieldOrder() {
List<Object> list = new ArrayList<>();
list.add("tmBuildTime");
list.add("sSerialNumber");
list.add("byChanNum");
list.add("uiDeviceRunTime");
list.add("deviceTpye");
return list;
}
}
public static class SDK_SYSTEM_TIME extends Structure{
public IntByReference year;
public IntByReference month;
public IntByReference day;
@Override
protected List<Object> getFieldOrder() {
List<Object> list = new ArrayList<>();
list.add("year");
list.add("month");
list.add("day");
return list;
}
}
// and then how I called it through the main function
public static void main(String args[]) throws FileNotFoundException{
simpleDLL INSTANCE = (simpleDLL) Native.loadLibrary( ("NetSdk"), simpleDLL.class);
DeviceDate dev = new DeviceDate() // where DeviceDate is a static class inherits com.sun.jna.Structure
int err = (int) INSTANCE.H264_GetLastError();
long result = INSTANCE.H264_Login("255.255.255.255", (short) 33333, "admin", "admin", dev, err, 0);
}
}
公共类测试实现StdCallLibrary{
公共接口SimpleDell扩展StdCallLibrary{
长H264_登录(字符串sIP、短wPort、字符串sUserName、字符串sPassword、,
结构DeviceDate,int error,int TCPSOCKET);
}
静止的
{
系统加载库(“NetSdk”);
}
//结构实现
公共静态类DeviceDate扩展结构{
公共SDK_系统_时间tmBuildTime;
公共字符串sSerialNumber;
拜占纳姆的公众参与;
公共IntByReference uiDeviceRunTime;
参考设备提供的公共输入;
@凌驾
受保护列表getFieldOrder(){
列表=新的ArrayList();
添加(“tmBuildTime”);
列表。添加(“sSerialNumber”);
添加(“拜占纳姆”);
列表。添加(“uiDeviceRunTime”);
列表。添加(“设备”);
退货清单;
}
}
公共静态类SDK\u系统\u时间扩展结构{
公众参与参考年;
公众参与参考月;
公众咨询日;
@凌驾
受保护列表getFieldOrder(){
列表=新的ArrayList();
列表。添加(“年度”);
列表。添加(“月份”);
列表。添加(“日”);
退货清单;
}
}
//然后我如何通过main函数调用它
公共静态void main(字符串args[])引发FileNotFoundException{
simpleDLL实例=(simpleDLL)Native.loadLibrary((“NetSdk”),simpleDLL.class);
DeviceDate dev=new DeviceDate()//其中DeviceDate是一个静态类,继承com.sun.jna.Structure
int err=(int)INSTANCE.H264_GetLastError();
长结果=INSTANCE.H264_登录(“255.255.255.255”,(短)33333,“admin”,“admin”,dev,err,0);
}
}
运行应用程序时,Java崩溃:
这是完整的问题签名:
public class Test implements StdCallLibrary {
public interface simpleDLL extends StdCallLibrary {
long H264_Login(String sIP, short wPort, String sUserName, String sPassword,
Structure DeviceDate, int error, int TCPSOCKET);
}
static
{
System.loadLibrary("NetSdk");
}
// the struct implementation
public static class DeviceDate extends Structure{
public SDK_SYSTEM_TIME tmBuildTime;
public String sSerialNumber;
public IntByReference byChanNum;
public IntByReference uiDeviceRunTime;
public IntByReference deviceTpye;
@Override
protected List<Object> getFieldOrder() {
List<Object> list = new ArrayList<>();
list.add("tmBuildTime");
list.add("sSerialNumber");
list.add("byChanNum");
list.add("uiDeviceRunTime");
list.add("deviceTpye");
return list;
}
}
public static class SDK_SYSTEM_TIME extends Structure{
public IntByReference year;
public IntByReference month;
public IntByReference day;
@Override
protected List<Object> getFieldOrder() {
List<Object> list = new ArrayList<>();
list.add("year");
list.add("month");
list.add("day");
return list;
}
}
// and then how I called it through the main function
public static void main(String args[]) throws FileNotFoundException{
simpleDLL INSTANCE = (simpleDLL) Native.loadLibrary( ("NetSdk"), simpleDLL.class);
DeviceDate dev = new DeviceDate() // where DeviceDate is a static class inherits com.sun.jna.Structure
int err = (int) INSTANCE.H264_GetLastError();
long result = INSTANCE.H264_Login("255.255.255.255", (short) 33333, "admin", "admin", dev, err, 0);
}
}
问题签名:问题事件名称:APPCRASH
应用程序名称:javaw.exe
应用程序版本:7.0.600.19
应用程序时间戳:536a95c6
故障模块名称:jna3976113557901128571.dll
故障模块版本:4.0.0.215
故障模块时间戳:52d3949a
异常代码:c0000005
异常偏移量:0000e3a2 OS 版本:6.1.7601.2.1.0.256.1
区域设置ID:1033
附加信息1:7bc2
附加信息2:7bc24d73a5063367529b81d28aecc01c
附加信息3:5bea
附加信息4:5beaa1c0441c3adb156a170a61c93d19 在线阅读我们的隐私声明:
如果在线隐私声明不可用,请阅读我们的 离线隐私声明:C:\Windows\system32\en US\erofflps.txt
您的映射有许多错误。您的结构应该如下所示(IntByReference表示传递
int
地址的位置,并且不能用String
替换原始的char
数组)。请参阅以确保您了解本机类型如何映射到Java类型:
public static class LP_DEVICE_INFO extends Structure{
public SDK_SYSTEM_TIME tmBuildTime;
public byte[] sSerialNumber = new byte[64];
public int byChanNum;
public int uiDeviceRunTime;
public int deviceType; // Assuming the size of the enum is int
@Override
protected List<Object> getFieldOrder() {
List<Object> list = new ArrayList<>();
list.add("tmBuildTime");
list.add("sSerialNumber");
list.add("byChanNum");
list.add("uiDeviceRunTime");
list.add("deviceTpye");
return list;
}
}
public static class SDK_SYSTEM_TIME extends Structure{
public int year;
public int month;
public int day;
@Override
protected List<Object> getFieldOrder() {
List<Object> list = new ArrayList<>();
list.add("year");
list.add("month");
list.add("day");
return list;
}
}
公共静态类LP\u DEVICE\u INFO扩展结构{
公共SDK_系统_时间tmBuildTime;
公共字节[]sSerialNumber=新字节[64];
拜占纳姆的公共关系;
公共设备运行时间;
public int deviceType;//假设枚举的大小为int
@凌驾
受保护列表getFieldOrder(){
列表=新的ArrayList();
添加(“tmBuildTime”);
列表。添加(“sSerialNumber”);
添加(“拜占纳姆”);
列表。添加(“uiDeviceRunTime”);
列表。添加(“设备”);
退货清单;
}
}
公共静态类SDK\u系统\u时间扩展结构{
公共国际年;
公众月;
公众国际日;
@凌驾
受保护列表getFieldOrder(){
列表=新的ArrayList();
列表。添加(“年度”);
列表。添加(“月份”);
列表。添加(“日”);
退货清单;
}
}
我无法理解那些只是来提问、否决投票、走开的人,至少要友善并留下评论,除非我的问题不符合网站常见问题解答,我确信它符合。请包括Java接口定义所基于的本机声明。@technomage好吧,我添加了所有必需的代码,请参阅我的更新。好吧,我更正了常规数据类型的映射,但我无法找出Java中与*LP_DEVICEINFO
对应的映射是什么,我尝试了很多方法(大多数都是对其他问题的回答),比如定义预定义大小的数组,通过引用声明结构并传递它,我自己声明nullDeviceDate[]
的方法,所有这些方法都会导致应用程序崩溃,尽管我的方法不会,但它不会返回一个带有预定义值的结构。你需要的是正确的结构定义(请参阅上面的LP\u DEVICE\u INFO
)。绝对不是Structure[]
或其他一些恰好正确地取消引用某些数据的任意排列。