Late binding with unmanaged code

G

Guest

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,
 
S

scott blood

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
 
G

Guest

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,
 
V

Vladimir Matveev

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,
 
S

scott blood

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


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,
 
G

Guest

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 .

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,
 
S

scott blood

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

Entwickler said:
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 .

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,
 
W

Willy Denoyette [MVP]

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
| 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 .
|
| "scott blood" wrote:
|
| > 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
| > > 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,
| >
| >
| >
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top