I am trying to load a "nicaiu.dll" in JAVA to acquire data using NI-DAQ devices.
I have converted the Native Library "nicaiu.dll" and the C Header "NIDAQmx.h" to a complete native bindings by JNAerator. But when I load the dll, there is a exception:
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
Here is the code about loading the 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);
I would like to know what's wrong with my way to load a dll, is it an error in my code or in the Dll?
You are running into a limitation of the ProxyGenerator class used by the reflection API, which keeps track of all the methods (and their arguments) that you are mapping.
It has a max byte size of 65535 when mapping methods and their arguments. Inspecting the source shows a few bytes of overhead plus a few more bytes per method and (probably most limiting) the full byte size of the method arguments.
If you have enough methods in your interface (with enough arguments each) you can easily exceed that limit. A brief search shows the limit exceeded with 1768 and ~2400 methods in two examples, suggesting at least 32 bytes used per method on average. Your API may be different, of course, but the bottom line is: you've mapped too many methods in a single Java class.
Using an automatic generator like JNAerator likely is producing many more methods than you actually need.
If you are only using a few methods from the API, you should attempt to map only those in your interface. If you are using most of them, you should try to split them up into multiple interfaces, grouped in some sensible functional organization.