使用JNA时,我在调用QLConnect
方法时收到无效内存访问错误。
下面是我映射DLL的接口:
import com.sun.jna.Native;
import com.sun.jna.win32.StdCallLibrary;
public interface QuikLimit extends StdCallLibrary {
QuikLimit INSTANCE = (QuikLimit) Native.load(new File("").getAbsolutePath() + "\\QuikLimit.dll", QuikLimit.class);
int QLConnect(String userName, String userPassword, byte[] desc);
//more methods from dll
}
我有另一个带有常量的类:
public class Const {
public static final int DESC_SIZE = 1024;
public enum Status {
//enum values
int code;
private Status(int code) {
this.code = code;
}
public int getCode() {
return code;
}
};
}
以下是代码中出现的位置:
@Component
public class ConnectionManager {
@Value("${quik.login}")
private String login;
@Value("${quik.password}")
private String password;
private Logger logger = LoggerFactory.getLogger(this.getClass());
private boolean connected;
public synchronized BaseResponse connect() {
BaseResponse result = new BaseResponse();
byte[] desc = new byte[Const.DESC_SIZE];
if (connected) {
//logic if connected
logger.info("call QLConnect");
int retVal = QuikLimit.INSTANCE.QLConnect(login, password, desc);
if (retVal == Const.Status.QL_ACTIVE.getCode()) {
//logic from response
} else if (retVal == Const.Status.QL_CONNECTEDNOTACTIVE.getCode()) {
//logic from response
}
result.setCode(retVal);
result.setDescription(Util.descToStr(desc));
QuikLimit.INSTANCE.QLDisconnect();
return result;
}
}
我知道1假设立即落在类型在dll中不匹配的事实上。但是头文件明确说明返回类型是int:
typedef __int32 ql_long;
ql_long _stdcall QLConnect(const char* lpszUserName, const char* lpszUserPassword, char* lpszError);
lpszUserName是指向包含用户名的ASCIIZ字符串的指针。
pszUserPassword是一个指向包含用户密码的ASCIIZ字符串的指针。
lpszDesc是一个指向缓冲区的指针,在出现错误的情况下,该缓冲区中的行及其描述。最小缓冲区大小为512字节。
还有什么可能是错误的原因?
当您收到“无效内存访问”错误时,首先要检查的是您的类型映射,您正确地从查看int
返回值开始。事实证明,其他参数的字符串
映射在 *nix 系统上工作正常,需要在 Windows 上进行一些特殊处理。
默认情况下,Windows使用UTF 16编码,JNA的默认类型映射试图将Java<code>String</code>对象转换为UTF-16编码的本地字符串(<code>wchar*</code>)。这对于Windows API DLL很好。
但是,您的自定义DLL指定用户名和密码参数应该是ASCIIZ格式(以空字符结尾的C字符串)。
您可以通过在加载DLL时包含W32APIOptions.ASCII_OPTIONS
作为第三个参数来强制JNA使用ASCIIString
类型映射器,例如,
QuikLimit INSTANCE = (QuikLimit) Native.load(new File("").getAbsolutePath() + "\\QuikLimit.dll", QuikLimit.class, W32APIOptions.ASCII_OPTIONS);
还有其他更细粒度的方法只处理String类型映射,这些方法不会尝试也执行函数映射(如果任何映射的函数以W或A结尾,这可能会中断!您可以深入研究 W32APIOptions
类,了解如何创建自己的自定义选项来传递。
问题内容: 我已经从事Java项目一年了。我的代码已经工作了好几个月了。几天前,我在Mac(Snow Leopard 10.6.8)上将Java SDK升级到最新版本1.6.0_26。升级后,发生了一些非常奇怪的事情。当我运行某些类时,出现此错误: 位置0x202 rip = 0x202的无效内存访问 但是,如果我使用- Xint(已解释)运行它们,它们会工作,但速度较慢,但效果很好。我在使用
问题内容: 我正在尝试直接为嵌入式Linux项目访问物理内存,但是我不确定如何最好地指定使用的内存。 如果我定期引导设备并访问/ dev / mem,则可以轻松地对其几乎任何位置进行读写。但是,在这种情况下,我正在访问可以轻松分配给任何进程的内存。我不想做 我的/ dev / mem代码是(删除了所有错误,等等。): 这可行。但是,我想使用没有其他人会碰到的内存。我尝试通过使用mem = XXXm
我正在使用tess4j.jar编写一个程序。该程序正在从图像中提取文本及其位置。我得到这个错误: 有趣的是,它不会出现在每张图片上。有人知道我哪里出错了吗? 这是我的代码:
我有一台在内部网8081端口上运行Nexus OSS存储库(版本3.15.1-01)的机器。我可以通过它的IP ping这台机器,我甚至Jenkins在8080端口上运行,可以通过任何互联网浏览器很好地访问它。然而,当我试图在8081上远程访问Nexus时,我只得到超时。 我已经在Nexus上配置了http/https代理(我们有一个公司代理),它可以毫无问题地从在线repos下载工件,并且我可以
问题内容: 示例代码: 问题行: 错误: 题: 那么,如何访问该界面内的键? 我是否需要使用方法集定义更复杂的接口来完成此操作? 问题答案: 由于您的分片类型为,因此索引该分片将为您提供type的元素。类型的值无法建立索引。 但是由于您将类型的值放入其中,因此可以使用类型断言来获取该映射类型的值,您可以对其进行正确索引: 输出(在Go Playground上尝试): 如果您知道总是将类型的值存储在
我正在尝试从intellij控制台访问内存中的H2数据库。我正在使用spring boot配置所有内容。连接字符串为:Spring。数据源。url=jdbc:h2:mem:testdb 当我使用intellij连接到数据库时,我看不到或查询表。我可以运行createtable命令来获取它,但仅此而已。这是该配置的图像: SHOW TABLES查询的结果不返回任何内容。 为什么我无法连接到此数据库?