1

How can you call a function in dll dynamically in C # without knowing the name of the library itself, but knowing the name of the function and its signature,( AND dll is not .NET!(sorry and Thank you))

  • How do you load an assembly if you don't know it's name? If you loaded it, you know the name. – sloth Sep 03 '13 at 13:40
  • 3
    Clarify, do you mean a .NET assembly library or a native library? Because the answers are highly different depending on which. – Lloyd Sep 03 '13 at 13:42
  • Look this question http://stackoverflow.com/questions/1202744/dynamically-p-invoking-a-dll – Pavel Voronin Sep 03 '13 at 13:42
  • 1
    I hope the name and/or signature are highly unique. Otherwise, you seem to be asking "How do I randomly invoke some code that I've no real knowledge of?" because you might accidentally select the wrong "match". – Damien_The_Unbeliever Sep 03 '13 at 13:45

5 Answers5

2

You could iterate through each assembly, in a known set of paths, starting with say the executable path. Load each assembly using the Assembly class, and then iterate through all of its types. On each type, simply iterate through the methods and see if one matches the signature.

This isn't very efficient, so once you find it I would recommend caching it.

So it might look something like this:

foreach (var file in Directory.GetFiles(path, "*.dll"))
{
    var a = Assembly.LoadFrom(file);
    foreach (var t in a.GetTypes())
    {
        foreach (var m in t.GetMethods())
        {
            // analyze the signature and see if it matches here
        }
    }
}

One thing to note about the *.dll search pattern:

When using the asterisk wildcard character in a searchPattern, such as "*.txt", the matching behavior when the extension is exactly three characters long is different than when the extension is more or less than three characters long. A searchPattern with a file extension of exactly three characters returns files having an extension of three or more characters, where the first three characters match the file extension specified in the searchPattern.

Mike Perrenoud
  • 66,820
  • 29
  • 157
  • 232
  • +1 It would be interesting to know if this is a side effect of the 8.3 filename creation, and if so, if it will work even on partitions where the 8.3 filename creation is disabled. – xanatos Sep 03 '13 at 13:54
  • 1
    Ah... And I think the `Assembly.LoadFrom` will throw if you try to load a native dll, so perhaps it would be better to try/catch the `Assembly.LoadFrom` – xanatos Sep 03 '13 at 13:59
  • @xanatos, that is correct, and so yeah a try-catch would be a perfect addition there. You wouldn't really need to do anything in the catch, just absorb it I would say. – Mike Perrenoud Sep 03 '13 at 14:02
  • It depends on how you do the try-catch. If you put everything (even the inner `foreach`s) in the try {} block then yes. If you put only the Assembly.LoadFrom in the try {} (something better I think, because in this way you can catch exceptions from Assebly.Load separately from exceptions of the called method) then you'll need to `continue`. – xanatos Sep 03 '13 at 14:07
  • Thank's, but if dll is not .NET? – Yury Bakharev Sep 03 '13 at 16:09
2

MEF is my favourite method of doing this, perticularly in larger projects where dependancy injection and IoC is helpful, MEF uses the techniques described by @neoistheone behind the scenes but in a much nicer API... One of it's main advantage is you get to avoid using reflection (which you can do some really clever things with, but it's ugly as sin).

You would typically have a 3rd dll (particularly for large projects) which contains interfaces to the classes/methods you'd like to load dynamically, both dlls reference this project and then you can load dlls from an assembly and dynamically access the defined interface. There are also multiple options to find assemblies to load dynamically -- of course this is all very flexible so you can stick to the 2 assemblies if you prefer.

I've found this sample on codeplex which might be a good starting point for you assuming you're not familiar with MEF. It does look like they have created a 4th superfluous executable assembly in their example as though this was to be used in a large scale project where they could've just imported the dynamically loaded assembly straight into the executable.

Dead.Rabit
  • 1,965
  • 1
  • 28
  • 46
1

As neoistheone replay is right i am just extracting the logic over here

foreach (var file in Directory.GetFiles(path, "*.dll"))
{
    var a = Assembly.LoadFrom(file);
    foreach (var t in a.GetTypes())
    {   
          //-- My code
          // Searches for the public method with the specified name.
          MethodInfo mInfo = t.GetMethod("YourMethodName");
          if(mInfo != null)
          {
             // method found
          }
          // Note :- The search for name is case-sensitive. The search includes public static and public instance methods.
          // -- End
    }
}

Reference link http://msdn.microsoft.com/en-us/library/8zz808e6.aspx
Simple logic is
1) Get all file libraries name (as you dont know which one is use full)
2) Write smart code for searching method on it.
I hope it will help you

Jageen
  • 6,345
  • 2
  • 37
  • 56
1

If the DLL is not a .NET assembly, then you will probably have to resort to "platform invoke" or PInvoke. See the MSDN tutorial here; there's also a site with most (if not all) of the common Windows internals at pinvoke.net.

The basic mechanism looks something like the following:

[DllImport("msvcrt.dll")]
public static extern int puts(char* s);

... at which point you can just use puts like a global function.

Of course this does require you to know the DLL name up front. Not sure how you'd get around that.

EDIT: See comment by @voroninp. Turns out my answer was superfluous ...

David
  • 2,226
  • 32
  • 39
0

You have to use reflection for this.

Check out more in the next article MethodBase.Invoke Method in Examples section.

RredCat
  • 5,259
  • 5
  • 60
  • 100