ExceptionInInitializerError: code size limit exceeded when loading a DLL in JNA
ExceptionInInitializerError: code size limit exceeded when loading a DLL in JNA
我正在尝试在 JAVA 中加载“nicaiu.dll”以使用 NI-DAQ 设备获取数据。
我已经通过 JNAerator 将原生库“nicaiu.dll”和 C Header“NIDAQmx.h”转换为完整的原生绑定。但是当我加载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错误?
您 运行 受到反射 API 使用的 ProxyGenerator class 的限制,反射会跟踪您正在映射的所有方法(及其参数)。
映射方法及其参数时,它的最大字节大小为 65535。检查源显示几个字节的开销加上每个方法的几个字节和(可能是最有限的)方法参数的完整字节大小。
如果您的接口中有足够多的方法(每个方法都有足够的参数),您很容易超过该限制。简短搜索显示两个示例中的 1768 and ~2400 方法超出了限制,建议平均每个方法至少使用 32 个字节。当然,您的 API 可能有所不同,但底线是:您在单个 Java class.
中映射了太多方法
使用像 JNAerator 这样的自动生成器生成的方法可能比您实际需要的多得多。
如果您只使用 API 中的几种方法,您应该尝试只映射您界面中的那些方法。如果您正在使用它们中的大部分,您应该尝试将它们拆分为多个接口,并按一些合理的功能组织进行分组。
我正在尝试在 JAVA 中加载“nicaiu.dll”以使用 NI-DAQ 设备获取数据。
我已经通过 JNAerator 将原生库“nicaiu.dll”和 C Header“NIDAQmx.h”转换为完整的原生绑定。但是当我加载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错误?
您 运行 受到反射 API 使用的 ProxyGenerator class 的限制,反射会跟踪您正在映射的所有方法(及其参数)。
映射方法及其参数时,它的最大字节大小为 65535。检查源显示几个字节的开销加上每个方法的几个字节和(可能是最有限的)方法参数的完整字节大小。
如果您的接口中有足够多的方法(每个方法都有足够的参数),您很容易超过该限制。简短搜索显示两个示例中的 1768 and ~2400 方法超出了限制,建议平均每个方法至少使用 32 个字节。当然,您的 API 可能有所不同,但底线是:您在单个 Java class.
中映射了太多方法使用像 JNAerator 这样的自动生成器生成的方法可能比您实际需要的多得多。
如果您只使用 API 中的几种方法,您应该尝试只映射您界面中的那些方法。如果您正在使用它们中的大部分,您应该尝试将它们拆分为多个接口,并按一些合理的功能组织进行分组。