Changed the license to the Mozilla Public License 2.0 and update the licensing information.
3 This Source Code Form is subject to the terms of the Mozilla Public
4 License, v. 2.0. If a copy of the MPL was not distributed with this
5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 Copyright (C) 2009-2010 Michael Möller <mmoeller@openhardwaremonitor.org>
12 using System.Collections.Generic;
13 using System.Reflection;
14 using System.Reflection.Emit;
15 using System.Runtime.InteropServices;
17 namespace OpenHardwareMonitor.Hardware {
19 internal static class PInvokeDelegateFactory {
21 private static readonly ModuleBuilder moduleBuilder =
22 AppDomain.CurrentDomain.DefineDynamicAssembly(
23 new AssemblyName("PInvokeDelegateFactoryInternalAssembly"),
24 AssemblyBuilderAccess.Run).DefineDynamicModule(
25 "PInvokeDelegateFactoryInternalModule");
27 private static readonly IDictionary<DllImportAttribute, Type> wrapperTypes =
28 new Dictionary<DllImportAttribute, Type>();
30 public static void CreateDelegate<T>(DllImportAttribute dllImportAttribute,
31 out T newDelegate) where T : class
34 wrapperTypes.TryGetValue(dllImportAttribute, out wrapperType);
36 if (wrapperType == null) {
37 wrapperType = CreateWrapperType(typeof(T), dllImportAttribute);
38 wrapperTypes.Add(dllImportAttribute, wrapperType);
41 newDelegate = Delegate.CreateDelegate(typeof(T), wrapperType,
42 dllImportAttribute.EntryPoint) as T;
46 private static Type CreateWrapperType(Type delegateType,
47 DllImportAttribute dllImportAttribute) {
49 TypeBuilder typeBuilder = moduleBuilder.DefineType(
50 "PInvokeDelegateFactoryInternalWrapperType" + wrapperTypes.Count);
52 MethodInfo methodInfo = delegateType.GetMethod("Invoke");
54 ParameterInfo[] parameterInfos = methodInfo.GetParameters();
55 int parameterCount = parameterInfos.GetLength(0);
57 Type[] parameterTypes = new Type[parameterCount];
58 for (int i = 0; i < parameterCount; i++)
59 parameterTypes[i] = parameterInfos[i].ParameterType;
61 MethodBuilder methodBuilder = typeBuilder.DefinePInvokeMethod(
62 dllImportAttribute.EntryPoint, dllImportAttribute.Value,
63 MethodAttributes.Public | MethodAttributes.Static |
64 MethodAttributes.PinvokeImpl, CallingConventions.Standard,
65 methodInfo.ReturnType, parameterTypes,
66 dllImportAttribute.CallingConvention,
67 dllImportAttribute.CharSet);
69 foreach (ParameterInfo parameterInfo in parameterInfos)
70 methodBuilder.DefineParameter(parameterInfo.Position + 1,
71 parameterInfo.Attributes, parameterInfo.Name);
73 if (dllImportAttribute.PreserveSig)
74 methodBuilder.SetImplementationFlags(MethodImplAttributes.PreserveSig);
76 return typeBuilder.CreateType();