ExceptionInInitializerError:在 JNA 中加载 DLL 时超出代码大小限制

Nic*_*ick 5 java reflection jna

我正在尝试在JAVA中加载“nicaiu.dll”以使用NI-DAQ设备获取数据。

我已将本机库“nicaiu.dll”和 C 标头“NIDAQmx.h”转换为 JNAerator 的完整本机绑定。但是当我加载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
Run Code Online (Sandbox Code Playgroud)

这是加载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
Run Code Online (Sandbox Code Playgroud)

我想知道我加载 dll 的方式有什么问题,是我的代码错误还是 Dll 错误?

Dan*_*dis 5

您遇到了反射 API 使用的ProxyGenerator 类的限制,该类跟踪您正在映射的所有方法(及其参数)。

映射方法及其参数时,它的最大字节大小为 65535。检查源代码显示了几个字节的开销加上每个方法的更多字节以及(可能是最有限的)方法参数的完整字节大小。

如果您的接口中有足够的方法(每个方法都有足够的参数),您可以轻松地超出该限制。简短的搜索显示两个示例中1768~2400 个方法超出了限制,表明每个方法平均至少使用 32 个字节。当然,您的 API 可能会有所不同,但底线是:您在单个 Java 类中映射了太多方法。

使用像 JNAerator 这样的自动生成器可能会生成比您实际需要的更多的方法。

如果您仅使用 API 中的少数方法,则应尝试仅映射界面中的那些方法。如果您正在使用其中的大部分,您应该尝试将它们分成多个界面,并按一些合理的功能组织进行分组。