gpt4 book ai didi

java.lang.Error : Invalid memory access on 32 bit Windows

转载 作者:行者123 更新时间:2023-12-04 07:26:20 36 4
gpt4 key购买 nike

我有一个 C DLL 的 JNA 包装器。它工作正常,除非在 Windows 32 位系统上使用。这是一个简化的示例:

int SetData(const wchar_t* data);

int SetId(const wchar_t* id, uint32_t flags);
我创建了 JNA 绑定(bind)如下:
public static native int SetData(WString data);

public static native int SetId(WString id, int flags);
第一个函数 SetData() 在 32 位和 64 位 Windows 上都可以正常工作,但第二个函数在 Windows 7 32 位上崩溃。
我尝试按照其他相关帖子中的建议使用 NativeLong,但没有帮助。
这是存储库的链接:
https://github.com/cryptlex/lexactivator-java/blob/master/src/main/java/com/cryptlex/lexactivator/LexActivatorNative.java

最佳答案

您的映射是正确的:WStringconst wchar_t* 的正确映射, 和 int (在 Java 中总是 32 位)是 uint32_t 的正确映射(总是 32 位),有一个关于签名的警告,当用作标志位掩码时应该无关紧要。
我不确定你在哪里读到的 NativeLong这里很合适。这主要用于 *nix native 代码,其中 sizeof(long)因操作系统位数而异。实际上,它在 Windows 上实际上并不重要,因为 LONG总是 32 位,但它涉及不必要的对象创建与原始对象。
JNA 抛出的“无效内存访问”错误是对 Structured Exception Handling 捕获的 native 内存错误的“优雅”处理。 .您真正需要知道的是 您正试图访问不属于您的 native 内存 您的 native 内存分配失败 .
调试这些错误总是涉及仔细跟踪内存分配。什么时候分配内存?什么时候发布?谁(Java 端或 native 端)负责此分配?当您尝试将数据从用户提供的 ID 字符串复制到您的 native DLL 正在访问的 native 内存时,您的程序可能会崩溃。所以这指向你需要调查的两个内存指针。

  • 查看正在写入 ID 字符串的内存。找出为它分配内存的时间。确保它对于字符串足够大(对于空终止符应该是 2x 字符串长度 + 2 个字节)并且正确归零(或明确附加一个空字节)。验证所有 WinAPI 调用都使用正确的(W 与 A)unicode 版本。
  • 我尝试添加 LA_IN_MEMORYflags位掩码并收到错误消息“试用尚未开始或已被篡改!试用天数:30”。这显然是由下一行( IsLicenseGenuine() )产生的,这意味着 setProductId()通话成功。
  • LA_IN_MEMORY 出现时,识别您的 native 代码的不同之处未设置标志可能会很有帮助。无效的内存访问可能与识别要使用的目录或文件有关。
  • 3.14.9 最近有一个涉及这个标志的变更日志条目。查看该提交可能会提示问题。
  • 3.15.0 中还有另一个最近的变化,涉及自动检测 Windows 上的文件,鉴于 LA_IN_MEMORY,这也可能是可疑的。使问题消失。

  • 当给出无效 key 时,错误消息“43:产品 ID 不正确”。返回,因此 native 代码中访问无主内存的点是在此错误检查之后。

  • 跟踪 Java 端定义的 ID 字符串发生的情况。鉴于字符串的常量定义,实际的内存分配可能不是问题,但请跟踪指向该字符串的 native 指针以确保它不会被无意中覆盖。

  • 正如您在评论中所指出的,减少 native 内存分配可以解决此问题,这表明您已达到限制。事实证明,堆栈大小 ( -Xss ) 的默认 32 位 Java native 内存分配为 320 KB。来自 Oracle docs :

    On Windows, the default thread stack size is read from the binary(java.exe). As of Java SE 6, this value is 320k in the 32-bit VM and1024k in the 64-bit VM.

    You can reduce your stack size by running with the -Xss option. Forexample:

    java -server -Xss64k

    Note that on some versions of Windows, the OS may round up threadstack sizes using very coarse granularity. If the requested size isless than the default size by 1K or more, the stack size is rounded upto the default; otherwise, the stack size is rounded up to a multipleof 1 MB.


    您可以增加此限制来解决问题,或者如您在备注中指出的那样,降低您的 native 分配。您可能希望比 300K 更保守,因为它只留下少量用于堆栈的其他用途。您也可以从较小的开始,检查 ERR_MORE_DATA 的返回值并用更大的值重试。 300KB 用于注册表值似乎是一个相当大的数量。
    另请注意,32 位 Java 具有 total process memory size limit of either 2GB or 4GB ,取决于操作系统。如果您的 Java 堆分配增长接近该限制,则会减少您可用的 native 数量。您可以使用 -Xmx 控制堆的大小。切换,您还可以使用 -Xss 确保足够的 native 内存分配转变。组合使用这些开关以避免达到进程大小限制。

    关于java.lang.Error : Invalid memory access on 32 bit Windows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68204722/

    36 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com