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)); }
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); }