|
Hello,
I'm new to C#, so please bear with me if the question is obvious and/or stupid.
I have a C# (.NET Framework 2.0) application that needs to call functions in an unmanaged C/C++ DLL. The name of the DLL is unknown at compile time (so I can't use the DllImportAttribute directly). The solution I adopted uses the native LoadLibrary/GetProcAddress combination, as seen in the code snippet below.
using System;
using System.Runtime.InteropServices;
namespace Simple
{
class DLLPlugin
{
[DllImport("kernel32", EntryPoint = "LoadLibrary")]
private static extern IntPtr LoadLibrary(string lpLibFileName);
[DllImport("kernel32", EntryPoint = "GetProcAddress", SetLastError = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
[DllImport("kernel32", EntryPoint = "FreeLibrary", SetLastError = true)]
private static extern bool FreeLibrary(IntPtr hModule);
public delegate void VoidVoidDelegate();
private VoidVoidDelegate RunDelegate;
private IntPtr moduleRef;
public DLLPlugin(string dllName)
{
moduleRef = LoadLibrary(dllName);
IntPtr pfn = GetProcAddress(moduleRef, "Run");
RunDelegate = (VoidVoidDelegate)
Marshal.GetDelegateForFunctionPointer(pfn, typeof(VoidVoidDelegate));
}
~DLLPlugin()
{
FreeLibrary(moduleRef);
}
public void Run()
{
RunDelegate();
}
}
}
In the code you'll see that I declared a delegate,
public delegate void VoidVoidDelegate();
private VoidVoidDelegate RunDelegate;
and then used it in the constructor to store the function I'm going to call in the DLL. In order to do that, I had to use the delegate type twice: once as a parameter for GetDelegateForFunctionPointer and then again to cast the return value.
Now, this example calls a function named Run that receives no arguments and returns nothing (void), as specified by the delegate signature.
Now, my problem is that I don't know this signature at compile time. Maybe the first time it runs, the Run function will receive two strings and return a bool. Or maybe it will receive a string, two bools, an int and return a double. Or maybe something else.
What I need is to supply the return and argument types, and then create at runtime the right kind of delegate to use. I would then use this delegate created at runtime to supply the correct signature to the GetDelegateForFunctionPointer method and to correctly cast the return value. Not to mention to call my function in the DLL, of course.
If someone has any suggestions, I'd greatly appreciate the help. Code examples as well to illustrate, since I'm not at all familiar with using Reflection.Emit (I'm assuming it's going to go that way?).
|
|
|
|
|
The code below should do what you want, but I have not tested it. The core code comes from here[^].
<br />
AssemblyName assembly = new AssemblyName();<br />
assembly.Version = new Version(1, 0, 0, 0);<br />
assembly.Name = "ReflectionEmitDelegateTest";<br />
<br />
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assembly,<br />
AssemblyBuilderAccess.Run);<br />
<br />
ModuleBuilder modbuilder = assemblyBuilder.DefineDynamicModule("MyModule", true);<br />
<br />
TypeBuilder typeBuilder = modbuilder.DefineType("MyDelegateType",<br />
TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed |<br />
TypeAttributes.AnsiClass | TypeAttributes.AutoClass,<br />
typeof(MulticastDelegate));<br />
<br />
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.RTSpecialName |<br />
MethodAttributes.HideBySig | MethodAttributes.Public,<br />
CallingConventions.Standard,<br />
new Type[] { typeof(object), typeof(System.IntPtr) });<br />
constructorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);<br />
<br />
Type[] paramTypes = new Type[2];<br />
paramTypes[0] = typeof(Int32);<br />
paramTypes[1] = typeof(String);<br />
<br />
MethodBuilder methodBuilder = typeBuilder.DefineMethod("Invoke",<br />
MethodAttributes.Public | MethodAttributes.HideBySig |<br />
MethodAttributes.NewSlot | MethodAttributes.Virtual,<br />
typeof(Int32),<br />
paramTypes);<br />
methodBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);<br />
<br />
Type type = typeBuilder.CreateType();<br />
<br />
Delegate del = Marshal.GetDelegateForFunctionPointer(pfn, type);<br />
del.DynamicInvoke(1, "2");<br />
Take care,
Tom
-----------------------------------------------
Check out my blog at http://tjoe.wordpress.com
|
|
|
|
|
It works! It's exactly what I needed. Thanks a lot for your help, I greatly appreciate it.
|
|
|
|
|
Help!
I have been using the dotNet Framework to create an UPnP Control Point application, this application makes use of the Microsoft UPNPLib.
The problem I have is when I "Invoke an Action", because the UPnP device that I am invoking the action on is building up a big response that could take a while to be received by my application the action keeps timing out (at around 36 seconds) is there anyway to extend the timeout period?
Freedom is the right to say that 2+2=5 if this is so everything else will follow.
|
|
|
|
|
Hi,
I have to compare MS Word Documents ie., the original document is to be compared with the same document after some editing and the process should be able to show the changes made. Please help me. The code should be in C#
thanx,
Nitin.
Nitin Raj Bidkikar
Nitin Raj Bidkikar
|
|
|
|
|
You already posted this 12 minutes ago. Why repost so soon?
|
|
|
|
|
i made the question more clear...........your answer didnt help.....got any other solution
Nitin Raj Bidkikar
|
|
|
|
|
Well there are probably libraries around that you can buy that will do this. There possibly code around for free, have you even tried searching? When you post here you should have atleast had a look around for something.
Assuming that you had searched I was fairly sure there wasn't going to be any free libraries which leaves you with the option of making your own ... which is why I gave the reply I did.
|
|
|
|
|
You can change your question after posting it, if you think you didn't make yourself clear the first time... No need to create a new question everytime.
Here's an article about a Diff engine you could use:
http://www.codeproject.com/cs/algorithms/diffengine.asp[^]
Regards,
mav
--
Black holes are the places where God divided by 0...
|
|
|
|
|
Hi all,
I want to download a file for every one minute from ftp server to client in .net(c#).
I got all the remaining code to download the file but could not find the method to include this timespan.
Please suggest me at the earliest.
Priya
|
|
|
|
|
You will need a Timer control for this. There are lots of examples on Google.
Cheers,
विक्रम
Be yourself, no matter what they say.
- Sting, Englishman in New York.
|
|
|
|
|
It worked.
Thanks and Regards,
Priya
|
|
|
|
|
i have to compare a word document which has been edited with the original ie., document before editing. how do i do this in c#.
Nitin Raj Bidkikar
|
|
|
|
|
|
Hi All
I am using crystal Report in C# 2005 asp.net
I want to export the crystal report to image (like Jpeg,Gif)
Any one please help me
it is very urgent
Sakti
|
|
|
|
|
I have an application in C# which should be installed on 10 machines.. I would like a way to make sure that they do not install on more than that. I would like to give them a way to activate each terminal. Since all terminals will be sharing a DataBase ,maybe we can have a verification process that asks them to input an activation code.Can any one help me regarding this?
|
|
|
|
|
If you don't mind spending the money you can use www.copyminder.com but if I were you I would request the names of the 10 computers and their IP Addresses that the application will be running on this way you can check if a computer is one of these 10 and if so allow the application to run otherwise not.
I know it's messy and probably not the best idea, but it will work.
Freedom is the right to say that 2+2=5 if this is so everything else will follow.
|
|
|
|
|
Hi,
Which one gives better performance, checking a string against null & empty.
string s = "something";
for(int i=0; i<100; i++) {
if(s != null) {
if(s.Length > 0) {
}
}
}
or
for(int i=0; i<100; i++) {
if(!String.IsNullOrEmpty(s)) {
}
}
plz help,
nas
|
|
|
|
|
put it in a loop that will run a few hundred thousand times and use the System.Diagnostics.StopWatch[^].
It's a good idea to get used to testing things like this yourself ... it's quicker than asking on here, more reliable and you have more chance of getting an answer with some of the more obscure stuff (not that IsNullOrEmpty is obsucre).
|
|
|
|
|
But he doesn't want to do any of the work himself. He needs someone to do his homework form him.
|
|
|
|
|
Or use Reflector to check what String.isNullOrEmpty does:
public static bool IsNullOrEmpty(string value)
{
if (value != null)
{
return (value.Length == 0);
}
return true;
}
IsNullOrEmpty is therefore just a bit slower because there is a strack frame more present (for calling the method). But compared to the time you are using in writing that every time, I'd use IsNullOrEmpty
-^-^-^-^-^-
no risk no funk ................... please vote ------>
|
|
|
|
|
Seriously, for the additional fractions of a microsecond that IsNullOrEmpty takes I wouldn't worry about it.
|
|
|
|
|
Won't .Length check for null again anyway? If so, you're checking for null twice.
I'd just use IsNullOrEmpty figuring Microsoft wouldn't steer me wrong. 
|
|
|
|
|
PIEBALDconsult wrote: Won't .Length check for null again anyway? If so, you're checking for null twice.
.Length cannot operate on null so it will throw an exception.
|
|
|
|
|
::Smacking forehead with heel of hand::
|
|
|
|