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 }