There are at least two methods to invoke function from unmamaged dll
using Reflecion.Emit.
1. Using DefinePInvokeMethod
public static object Invoke(string dllName, string function,
object[] args, Type resultType)
{
Type[] argTypes = Type.GetTypeArray(args);
CultureInfo ci = Thread.CurrentThread.CurrentCulture;
AssemblyName asmName = new AssemblyName();
asmName.Name = "TempAssembly";
asmName.Version = new Version(1, 0, 0, 0);
asmName.CultureInfo = ci;
AssemblyBuilder asmBuilder =
Thread.GetDomain().DefineDynamicAssembly(asmName,
AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder =
asmBuilder.DefineDynamicModule("TempModule");
MethodBuilder mb = moduleBuilder.DefinePInvokeMethod(function,
dllName,
MethodAttributes.Final | MethodAttributes.PinvokeImpl |
MethodAttributes.Public | MethodAttributes.Static,
CallingConventions.Standard,
resultType,
argTypes,
CallingConvention.Winapi,
CharSet.Unicode);
moduleBuilder.CreateGlobalFunctions();
MethodInfo mi = moduleBuilder.GetMethod(function);
return mi.Invoke(null, args);
}
2. Using DllImport attribute
public static object Invoke(string dllName, string function,
object[] args, Type resultType)
{
Type[] argTypes = Type.GetTypeArray(args);
CultureInfo ci = Thread.CurrentThread.CurrentCulture;
AssemblyName asmName = new AssemblyName();
asmName.Name = "TempAssembly";
asmName.Version = new Version(1, 0, 0, 0);
asmName.CultureInfo = ci;
AssemblyBuilder asmBuilder =
Thread.GetDomain().DefineDynamicAssembly(asmName,
AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder =
asmBuilder.DefineDynamicModule("TempModule");
MethodBuilder methodBuilder =
moduleBuilder.DefineGlobalMethod(function,
MethodAttributes.Final | MethodAttributes.PinvokeImpl |
MethodAttributes.Public | MethodAttributes.Static,
CallingConventions.Standard,
resultType,
argTypes);
Type dllImportType = typeof(DllImportAttribute);
ConstructorInfo conInfo = dllImportType.GetConstructor(new Type[]
{typeof(string)} );
FieldInfo callingConvField =
dllImportType.GetField("CallingConvention");
FieldInfo preserveSigField =
dllImportType.GetField("PreserveSig");
FieldInfo charSetField = dllImportType.GetField("CharSet");
CustomAttributeBuilder attrBuilder = new CustomAttributeBuilder(
conInfo,
new object[] {dllName},
new PropertyInfo[0],
new object[0],
new FieldInfo[] {callingConvField, preserveSigField,
charSetField},
new object[] {CallingConvention.Winapi, true, CharSet.Unicode}
);
methodBuilder.SetCustomAttribute(attrBuilder);
moduleBuilder.CreateGlobalFunctions();
MethodInfo mi = moduleBuilder.GetMethod(function);
return mi.Invoke(null, args);
}
Entwickler said:
Hello scott,
thank you for your reply. i am trying to apply the code you send but it is
looking like i am missing a namespace . when i try to compile i become the
following errors :
"The name 'LoadLibrary' does not exist in the current context"
"The name 'GetProcAddress' does not exist in the current context"
i am using the following namespaces :
using System.Reflection.Emit;
using System.Reflection;
using System.Runtime.InteropServices;
I don't know if i am missing a namespace .
thanks.
scott blood said:
Hello,
Unfortunatly you cannot call unmanaged code using late binding in this
method.
Please review the following code which should help you
[DllImport("Invoke", CharSet=CharSet.Unicode)]
public extern static int InvokeFunc(int funcptr, int hwnd, string message,
string title, int flags);
int hmod=LoadLibrary("MyLib.dll");
int funcaddr=GetProcAddress(hmod, "MyFunction");
int result=InvokeFunc(funcaddr, 0, "Hello World", ".test", 1);
FreeLibrary(hmod);
Regards
Scott Blood
C# Developer
Entwickler said:
hello,
i have the following problem. i want to write a code that enables the user
to call functions from a unmanaged code .dll at running time . so i have
to
use the late binding . i tried the following code but it doesn't walk :
Assembly assemblyInstance =
Assembly.LoadFrom(@"C:\myData\UnmanagedCode.dll");
i don't know if somebody can help me .
Regards,