/// <summary>
        /// Load a native interface
        /// </summary>
        /// <returns></returns>
        public object?LoadNativeInterface(Type t)
        {
            if (!t.IsInterface)
            {
                throw new InvalidOperationException($"{t.Name} must be an interface");
            }

            if (LibraryLoader == null)
            {
                throw new InvalidOperationException("A native library is not already loaded");
            }

            var ilGenerator        = new CalliILGenerator();
            var interfaceGenerator = new InterfaceGenerator(LibraryLoader, ilGenerator);

            return(interfaceGenerator.GenerateImplementation(t));
        }
        /// <summary>
        /// Load a native interface
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T?LoadNativeInterface <T>() where T : class
        {
            if (!typeof(T).IsInterface)
            {
                throw new InvalidOperationException($"{typeof(T).Name} must be an interface");
            }

            if (LibraryLoader == null)
            {
                throw new InvalidOperationException("A native library is not already loaded");
            }

            var ilGenerator        = new CalliILGenerator();
            var interfaceGenerator = new InterfaceGenerator(LibraryLoader, ilGenerator);

            return(interfaceGenerator.GenerateImplementation <T>());
        }
        public void TestCalliGenerationVoidVoid()
        {
            int    callCount = 0;
            Action vvct      = () =>
            {
                callCount++;
            };
            var fp = Marshal.GetFunctionPointerForDelegate(vvct);
            CalliILGenerator generator = new CalliILGenerator();
            DynamicMethod    method    = new DynamicMethod("MyFunc", null, null);

            generator.GenerateMethod(method.GetILGenerator(), null, null, fp);

            method.Invoke(null, null);

            Assert.Equal(1, callCount);
        }
        public void TestCalliGenerationVoidIntStar()
        {
            int          callCount = 0;
            int          setVal    = 5;
            Take1IntStar vvct      = (i) =>
            {
                callCount++;
                *i = *i + 1;
            };
            var fp = Marshal.GetFunctionPointerForDelegate(vvct);
            CalliILGenerator generator = new CalliILGenerator();
            DynamicMethod    method    = new DynamicMethod("MyFunc", null, new Type[] { typeof(int *) });

            generator.GenerateMethod(method.GetILGenerator(), null, new Type[] { typeof(int *) }, fp);

            method.Invoke(null, new object[] { Pointer.Box(&setVal, typeof(int *)) });

            Assert.Equal(1, callCount);
            Assert.Equal(6, setVal);
        }
        public void TestCalliGenerationIntInt()
        {
            int            callCount = 0;
            int            setVal    = 0;
            TakeReturn1Int vvct      = (i) =>
            {
                callCount++;
                setVal = i;
                return(i + 1);
            };
            var fp = Marshal.GetFunctionPointerForDelegate(vvct);
            CalliILGenerator generator = new CalliILGenerator();
            DynamicMethod    method    = new DynamicMethod("MyFunc", typeof(int), new Type[] { typeof(int) });

            generator.GenerateMethod(method.GetILGenerator(), method.ReturnType, new Type[] { typeof(int) }, fp);

            var ret = method.Invoke(null, new object[] { 5 });

            Assert.Equal(1, callCount);
            Assert.Equal(5, setVal);
            Assert.Equal(6, ret);
        }