java - ExceptionInInitializerError : code size limit exceeded when loading a DLL in JNA

标签 java reflection jna

我正在尝试在 JAVA 中加载“nicaiu.dll”以使用 NI-DAQ 设备获取数据。
我已将 native 库“nicaiu.dll”和 C 头文件“NIDAQmx.h”转换为 JNAerator 的完整 native 绑定(bind)。但是当我加载dll时,出现了一个异常:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at TestDAQ.main(TestDAQ.java:151)
Caused by: java.lang.IllegalArgumentException: code size limit exceeded
    at sun.misc.ProxyGenerator.generateStaticInitializer(ProxyGenerator.java:1261)
    at sun.misc.ProxyGenerator.generateClassFile(ProxyGenerator.java:484)
    at sun.misc.ProxyGenerator.generateProxyClass(ProxyGenerator.java:339)
    at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:639)
    at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:557)
    at java.lang.reflect.WeakCache$Factory.get(WeakCache.java:230)
    at java.lang.reflect.WeakCache.get(WeakCache.java:127)
    at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:419)
    at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:719)
    at com.sun.jna.Native.loadLibrary(Native.java:415)
    at com.sun.jna.Native.loadLibrary(Native.java:391)
    at org.xjtu.nidaqmx4j.NicaiuLibrary.<clinit>(NicaiuLibrary.java:29)
    ... 1 more
这是关于加载dll的代码
public static final String JNA_LIBRARY_NAME = "nicaiu";
    public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(NicaiuLibrary.JNA_LIBRARY_NAME);
    public static final NicaiuLibrary INSTANCE = (NicaiuLibrary)Native.loadLibrary(NicaiuLibrary.JNA_LIBRARY_NAME, NicaiuLibrary.class);
我想知道我加载 dll 的方式有什么问题,是我的代码或 Dll 中的错误吗?

最佳答案

您遇到了 ProxyGenerator class 的限制。由反射 API 使用,它跟踪您正在映射的所有方法(及其参数)。
映射方法及其参数时,它的最大字节大小为 65535。检查源会显示几个字节的开销加上每个方法的更多字节以及(可能是最有限的)方法参数的完整字节大小。
如果您的接口(interface)中有足够多的方法(每个方法都有足够的参数),您可以轻松超过该限制。简短的搜索显示 1768 超出了限制。和 ~2400两个示例中的方法,建议每个方法平均至少使用 32 个字节。当然,您的 API 可能有所不同,但底线是:您在单个 Java 类中映射了太多方法。
使用像 JNAerator 这样的自动生成器可能会产生比您实际需要的更多的方法。
如果您只使用 API 中的几个方法,则应尝试仅映射您界面中的那些方法。如果您使用其中的大部分,您应该尝试将它们拆分为多个接口(interface),并按一些合理的功能组织进行分组。

关于java - ExceptionInInitializerError : code size limit exceeded when loading a DLL in JNA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62770339/

相关文章:

java - 我想为 jOOQ 生成的类添加注释

java - Java中的多节点并发

java - 在Java中执行RFC计算的算法

java - 使用 Java Reflection 获取运行时上下文中所有定义的变量(内部有 voodoo)

java - 通过 JNA 调用 COM 接口(interface)时出现无效内存访问异常

Java + JNA,寻找运行ShellExecuteW的方法

java - 使用 c 访问映射中的值 :out tag

java - 从基类创建多个对象的更简洁的方法

Java getMethod 抛出方法未找到异常?

java - 如何在 JNA 中映射枚举