/// /// Copyright © 2003-2008 JetBrains s.r.o. /// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder). /// using System; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; namespace JetBrains.Build.Omea.Resolved.Infra { /// /// Creates a runtime wrapper around an exported function of a native DLL. /// public class DynamicPinvoke : IDisposable { #region Data private static MethodInfo myMethod; #endregion #region Init /// /// Creates a runtime PInvoke wrapper for the DLL's function. /// /// The DLL to invoke into. /// A name of the DLL's exported function. /// The return type of the exported function. /// Argument types of the exported function. public DynamicPinvoke(FileInfo fiDll, string sFunctionName, Type typeReturn, params Type[] typeArgs) { Setup(fiDll, sFunctionName, typeReturn, typeArgs); } #endregion #region Operations /// /// Invokes the wrapped method. /// public object Invoke(params object[] args) { return myMethod.Invoke(null, args); } #endregion #region Implementation /// /// Creates a runtime PInvoke wrapper for the DLL's function. /// /// The DLL to invoke into. /// A name of the DLL's exported function. /// The return type of the exported function. /// Argument types of the exported function. private static void Setup(FileInfo fiDll, string sFunctionName, Type typeReturn, params Type[] typeArgs) { var assemblyName = new AssemblyName(); assemblyName.Name = "wixTempAssembly"; AssemblyBuilder dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run | AssemblyBuilderAccess.Save, fiDll.Directory.FullName); ModuleBuilder dynamicModule = dynamicAssembly.DefineDynamicModule(assemblyName.Name, assemblyName.Name + ".dll"); MethodBuilder dynamicMethod = dynamicModule.DefinePInvokeMethod(sFunctionName, fiDll.FullName, MethodAttributes.Static | MethodAttributes.Public | MethodAttributes.PinvokeImpl | MethodAttributes.HideBySig, CallingConventions.Standard, typeReturn, typeArgs, CallingConvention.Winapi, CharSet.Ansi); dynamicMethod.SetImplementationFlags(MethodImplAttributes.PreserveSig); dynamicModule.CreateGlobalFunctions(); myMethod = dynamicModule.GetMethod(sFunctionName); } #endregion #region IDisposable Members /// ///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// ///2 public void Dispose() { } #endregion } }