Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / March 2006

Tip: Looking for answers? Try searching our database.

Late binding with unmanaged code

Thread view: 
Enable EMail Alerts  Start New Thread
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 Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.