///
/// 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
}
}