.NET Forum / Languages / C# / March 2006
Late binding with unmanaged code
|
|
Thread rating:  |
Entwickler - 16 Mar 2006 09:42 GMT 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,
scott blood - 16 Mar 2006 09:54 GMT 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
> hello, > i have the following problem. i want to write a code that enables the user [quoted text clipped - 5 lines] > i don't know if somebody can help me . > Regards, Entwickler - 16 Mar 2006 11:27 GMT 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.
> Hello, > [quoted text clipped - 26 lines] > > i don't know if somebody can help me . > > Regards, Vladimir Matveev - 16 Mar 2006 11:47 GMT 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); }
> Hello scott, > thank you for your reply. i am trying to apply the code you send but it is [quoted text clipped - 40 lines] > > > i don't know if somebody can help me . > > > Regards, scott blood - 16 Mar 2006 12:01 GMT hello,
My Apologies i ommited a number of import calls, was too busy drinking my morning brew.
[DllImport("kernel32")] public extern static IntPtr LoadLibrary(string lpLibFileName);
[DllImport("kernel32")] public extern static Int32 FreeLibrary(IntPtr hModule);
I cant off the top of my head remember where GetProcAadress comes from, i think it is Kernal32.
I wonder can someone else show an example of importing GetProcAddress
Regards Scott Blood C# Developer
> Hello scott, > thank you for your reply. i am trying to apply the code you send but it is [quoted text clipped - 43 lines] >> > i don't know if somebody can help me . >> > Regards, Entwickler - 16 Mar 2006 14:30 GMT hello scott, Thank you for the details . I really appreciate the way you are participating in this Forum. i tried to apply it and it walks , but i realised that i muss enter the dll's and the function's name at programming time.. May be i muss tell you exactly what i want . I want to allow the user of my programm to call a function in any dll he wants. The user will give the path of the dll in an Textbox , and the programm will load the dll and display the name of the functions that are in this dll. after that , the user can choose which function he wants to call. I Hope you can understand me better now, and Sorry that i didn't explain it clearly at the beginning. I was thinking that it's clear enough, but it wasn't. Thanks .
> Hello, > [quoted text clipped - 26 lines] > > i don't know if somebody can help me . > > Regards, scott blood - 16 Mar 2006 15:07 GMT Ok,
I understand what you want now :), unfortunatly my knowledge of the WINAPI is limited to loading a known function, i am not sure how to load a list of functions in a dll :(
I will however ask around and if no one posts here before then i will post a reply :)
Regards Scott Blood C# Developer
> hello scott, > Thank you for the details . I really appreciate the way you are [quoted text clipped - 45 lines] >> > i don't know if somebody can help me . >> > Regards, Willy Denoyette [MVP] - 16 Mar 2006 23:43 GMT You can't call arbitrary functions in arbitrary DLL's, let me explain. First you need to create a delegate from the pointer returned from GetProcAddress, but the delegate needs to be defined in code before you can call it.
Take following code snip:
delegate double Proc(possible arguments);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true)] public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); [DllImport("kernel32.dll")] static extern IntPtr LoadLibrary(string lpFileName); static void Main() { IntPtr modulePtr = LoadLibrary("some.dll"); if (modulePtr == IntPtr.Zero) { MessageBox.Show(Marshal.GetLastWin32Error().ToString()); return; } IntPtr pPtr = GetProcAddress(modulePtr, "SomeExportedFunction"); Proc p = (Proc)Marshal.GetDelegateForFunctionPointer(pPtr, typeof(Proc)); Console.WriteLine(p(possible args.));
Here I load the library "some.dll", get the procedure address of a single function "SomeExportedFunction", create a delegate from this function pointer returned from GetProcAddress and finally call the function through the delegate. Ok, that's easy, but you are trying to call whatever function exported from the DLL. But there are some issues to solve, how are you going to get: 1. The function names exported by the DLL?, 2. how do you think to get to know the arguments of the functions?, 3. how do you think to get something returned from a function (a return value or an out argument)? Some of these issues can be solved by calling some unmanaged API's, but you won't get at the arg. types, nor can you return something from the functions without generating a bunch of dynamic code. Sorry, but I don't see what's the use of this, unless you are trying to call a limited number of well known functions from some well known libraries.
Willy.
| hello scott, | Thank you for the details . I really appreciate the way you are [quoted text clipped - 42 lines] | > > i don't know if somebody can help me . | > > Regards,
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|