1

如何在 C# 中动态调用 dll 中的函数而不知道库本身的名称,但知道函数的名称及其签名,(并且 dll 不是 .NET!(对不起,谢谢))

4

5 回答 5

1

您可以在一组已知的路径中迭代每个程序集,从可执行路径开始。使用该类加载每个程序集Assembly,然后遍历其所有类型。在每种类型上,只需遍历方法并查看是否与签名匹配。

这不是很有效,所以一旦你找到它,我会建议缓存它。

所以它可能看起来像这样:

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
        }
    }
}

*.dll关于搜索模式需要注意的一件事:

在 searchPattern 中使用星号通配符(例如“*.txt”)时,扩展名正好是三个字符长时的匹配行为与扩展名长度多于或少于三个字符时的匹配行为不同。文件扩展名正好为三个字符的 searchPattern 返回具有三个或更多字符扩展名的文件,其中前三个字符与 searchPattern 中指定的文件扩展名匹配。

于 2013-09-03T13:40:35.273 回答
1

MEF是我最喜欢的方法,特别是在依赖注入和 IoC 很有帮助的大型项目中,MEF 在幕后使用@neoistheone 描述的技术,但在一个更好的 API 中......它的主要优势之一是你可以避免使用反射(你可以用它做一些非常聪明的事情,但它像罪恶一样丑陋)。

您通常会有一个第三个 dll(特别是对于大型项目),其中包含您想要动态加载的类/方法的接口,两个 dll 都引用该项目,然后您可以从程序集中加载 dll 并动态访问定义的接口。还有多个选项可以找到要动态加载的程序集——当然,这非常灵活,因此如果您愿意,您可以坚持使用 2 个程序集。

我在 codeplex 上找到了这个示例,假设您不熟悉 MEF,这可能是一个很好的起点。看起来他们在他们的示例中创建了第 4 个多余的可执行程序集,就好像这是要在大型项目中使用的那样,他们可以将动态加载的程序集直接导入可执行文件。

于 2013-09-03T13:54:05.033 回答
0

你必须为此使用反射。

在下一篇文章MethodBase.Invoke Method in Examples部分中查看更多信息。

于 2013-09-03T13:47:09.517 回答
0

由于neoistheone重播是正确的,我只是在这里提取逻辑

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
    }
}

参考链接http://msdn.microsoft.com/en-us/library/8zz808e6.aspx
简单的逻辑是
1)获取所有文件库名称(因为你不知道哪个使用完整)
2)编写搜索方法的智能代码在上面。
我希望它会帮助你

于 2013-09-03T14:08:22.937 回答
0

如果 DLL 不是 .NET 程序集,那么您可能不得不求助于“平台调用”或 PInvoke。请参阅此处的 MSDN 教程;这里还有一个包含大多数(如果不是全部)常见 Windows 内部组件的站点。

基本机制如下所示:

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

...此时您可以puts像使用全局函数一样使用。

当然,这确实需要您预先知道 DLL 名称。不知道你会如何解决这个问题。

编辑:见@voroninp 的评论。原来我的回答是多余的......

于 2013-09-03T16:47:04.357 回答