001    package org.bridj;
002    
003    import org.bridj.CRuntime.MethodCallInfoBuilder;
004    import org.bridj.ann.Convention;
005    import java.lang.reflect.Constructor;
006    import java.lang.reflect.Method;
007    
008    import static org.bridj.Pointer.*;
009    
010    /**
011     * Factory that is able to create dynamic functions bindings with a given signature
012     */
013    public class DynamicFunctionFactory {
014    
015        final Constructor<? extends DynamicFunction> constructor;
016        final Method method;
017        final long callbackHandle;
018    
019        DynamicFunctionFactory(Class<? extends DynamicFunction> callbackClass, Method method, /*Convention.Style style,*/ MethodCallInfoBuilder methodCallInfoBuilder) {
020            try {
021                this.constructor = callbackClass.getConstructor();
022                this.method = method;
023                
024                MethodCallInfo mci = methodCallInfoBuilder.apply(method);
025                callbackHandle = JNI.bindJavaToCCallbacks(mci);
026            } catch (Throwable th) {
027                th.printStackTrace();
028                throw new RuntimeException("Failed to instantiate callback" + " : " + th, th);
029            }
030        }
031    
032        @Override
033        protected void finalize() throws Throwable {
034            if (BridJ.debugNeverFree)
035                            return;
036                    
037                    JNI.freeJavaToCCallbacks(callbackHandle, 1);
038        }
039    
040    
041        public DynamicFunction newInstance(Pointer<?> functionPointer) {
042            if (functionPointer == null)
043                return null;
044            
045            try {
046                DynamicFunction dcb = constructor.newInstance();
047                dcb.peer = (Pointer) functionPointer;
048                dcb.method = method;
049                dcb.factory = this;
050                
051                return dcb;
052            } catch (Throwable th) {
053                th.printStackTrace();
054                throw new RuntimeException("Failed to instantiate callback" + " : " + th, th);
055            }
056        }
057    
058        @Override
059        public String toString() {
060            return getClass().getSimpleName() + "(" + method + ")";
061        }
062    
063    
064    }