Beispiel #1
0
        static object DoCreate(ModuleBuilder mb, Type t)
        {
            NativeDllAttribute[] dllAttributes = (NativeDllAttribute[])t.GetCustomAttributes(typeof(NativeDllAttribute), false);
            if (dllAttributes.Length == 0)
            {
                throw new Exception("Interface must be marked with CK.Interop.NativeDllAttribute.");
            }
            string defaultDllName = dllAttributes[0].GetBestDefaultName();

            TypeBuilder type = mb.DefineType(String.Format("CK_Dyn_{0}_{1}", t.Name, ++_countName));

            type.AddInterfaceImplementation(t);

            foreach (MethodInfo m in t.GetMethods())
            {
                DllImportAttribute a = (DllImportAttribute)Attribute.GetCustomAttribute(m, typeof(DllImportAttribute), false);
                if (a != null)
                {
                    // DllName
                    string dllName = a.GetBestDllName(defaultDllName);

                    // Extract parameters type.
                    Type[] parameterTypes = ReflectionHelper.CreateParametersType(m.GetParameters());

                    MethodBuilder nativeMethod = CreateNative(type, dllName, m, a, parameterTypes);

                    MethodBuilder method = type.DefineMethod(m.Name,
                                                             MethodAttributes.Public | MethodAttributes.Virtual,
                                                             m.ReturnType,
                                                             parameterTypes);
                    ILGenerator g = method.GetILGenerator();
                    g.RepushActualParameters(false, parameterTypes.Length);
                    g.EmitCall(OpCodes.Call, nativeMethod, null);
                    g.Emit(OpCodes.Ret);
                }
            }
            Type finalType = type.CreateType();

            return(Activator.CreateInstance(finalType));
        }
Beispiel #2
0
        private static MethodBuilder CreateNative(TypeBuilder tb, string dllName, MethodInfo m, DllImportAttribute a, Type[] parameterTypes)
        {
            // This code is from msdn itself (the example associated to TypeBuilder.DefinePInvokeMethod).
            MethodBuilder native = tb.DefineMethod("_st_" + m.Name, MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.HideBySig, m.ReturnType, parameterTypes);

            // Create an array of values to assign to the fields of the
            // DLLImportAttribute class, when constructing an attribute
            // for the native function.
            object[] fieldvalues = new object[]
            {
                a.GetBestEntryPoint(m.Name),
                a.ExactSpelling,
                a.PreserveSig,
                a.SetLastError,
                a.CallingConvention,
                a.CharSet,
                a.BestFitMapping,
                a.ThrowOnUnmappableChar
            };

            // Construct a DLLImportAttribute.
            CustomAttributeBuilder attr = new CustomAttributeBuilder(_impAttrCtor, new object[] { dllName }, _impAttrFields, fieldvalues);

            // Apply the DLLCustomAttribute to the PInvoke method.
            native.SetCustomAttribute(attr);

            // The PInvoke method does not have a method body.
            return(native);
        }