【问题标题】:C# Using Assembly to call a method within a DLLC# 使用程序集调用 DLL 中的方法
【发布时间】:2011-07-31 19:25:38
【问题描述】:

我已经阅读了很多关于此的内容 - 我觉得我非常接近答案。我只是想从我创建的 dll 文件中调用一个方法。

例如目的:

我的 DLL 文件:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ExampleDLL
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Windows.Forms.MessageBox.Show(args[0]);
        }

        public void myVoid(string foo)
        {
            System.Windows.Forms.MessageBox.Show(foo);
        }
    }
}


我的应用程序:

string filename = @"C:\Test.dll";
    Assembly SampleAssembly;
    SampleAssembly = Assembly.LoadFrom(filename);
    // Obtain a reference to a method known to exist in assembly.
    MethodInfo Method = SampleAssembly.GetTypes()[0].GetMethod("myVoid");
    // Obtain a reference to the parameters collection of the MethodInfo instance.

以上 sn-p 的所有功劳都归于 SO 用户 'woohoo' How to call a Managed DLL File in C#?

不过,现在,我希望不仅能够引用我的 Dll(以及其中的方法),而且能够正确调用其中的方法(在这种情况下,我想调用方法“myVoid”)。

有人对我有什么建议吗?

谢谢,

埃文

【问题讨论】:

  • 为什么不将其引用添加到您的应用程序中?
  • @SaberAmani:因为如果用户有权访问该功能,OP 可能只想包含 DLL。添加的参考必须始终随应用一起提供。
  • 在某些情况下,您需要单独发布同一应用程序的模块。初始安装包含基本功能,而升级包使用基本功能 dll 访问某种数据上下文,而无需在升级包中重写相同的代码。

标签: c# dll assemblies


【解决方案1】:

您引用的问题和答案是使用反射来调用托管DLL中的方法。如果正如您所说,您只是引用您的 DLL,则这不是必需的。添加引用(通过 Visual Studio 中的添加引用选项),您可以像这样直接调用您的方法:

ExampleDLL.Program p = new ExampleDLL.Program(); // get an instance of `Program`
p.myVoid(); // call the method `myVoid`

如果你想走反射路线(由woohoo 给出),你仍然需要一个Program 类的实例。

Assembly SampleAssembly = Assembly.LoadFrom(filename);
Type myType = SampleAssembly.GetTypes()[0];
MethodInfo Method = myType.GetMethod("myVoid");
object myInstance = Activator.CreateInstance(myType);
Method.Invoke(myInstance, null);

现在你有一个Program 的实例并且可以调用myVoid

【讨论】:

  • 你也需要设置参数
  • @DSW:阅读 MethodInfo.Invoke 的文档。
  • 感谢您提醒我阅读文档:) 但我想知道如何在不提供参数的情况下调用 myvoid 方法,它应该是 object result = method.Invoke(null , 参数);
  • 这将调用myVoid 作为带有参数parameters 的静态方法。可能给参数一个空数组很好,但我喜欢坚持文档的字母。
  • @Matthew Ferreira 作为对我最初的问题的某种跟进,(你真的让我想到这里),是否可以在将我的 dll 文件添加为我的项目的引用之前对其进行加密;然后,将dll的数据作为某个对象加载,解密这些数据,仍然可以调用其中的方法吗?
【解决方案2】:
//Assembly1.dll
using System;
using System.Reflection;

namespace TestAssembly
{
    public class Main
    {
        public void Run(string parameters)
        {
            // Do something... 
        }
        public void TestNoParameters()
        {
            // Do something... 
        }
    }
}

//Executing Assembly.exe
public class TestReflection
{
    public void Test(string methodName)
    {
        Assembly assembly = Assembly.LoadFile("...Assembly1.dll");
        Type type = assembly.GetType("TestAssembly.Main");
        if (type != null)
        {
            MethodInfo methodInfo = type.GetMethod(methodName);
            if (methodInfo != null)
            {
                object result = null;
                ParameterInfo[] parameters = methodInfo.GetParameters();
                object classInstance = Activator.CreateInstance(type, null);
                if (parameters.Length == 0)
                {
                    result = methodInfo.Invoke(classInstance, null);
                }
                else
                {
                    object[] parametersArray = new object[] { "Hello" };

                    result = methodInfo.Invoke(classInstance, parametersArray);
                }
            }
        }
    }
}

【讨论】:

    【解决方案3】:

    在你获得对你的方法的引用后添加这行代码。

                Method.Invoke(classInstance, new object[] {});
    

    希望对您有所帮助。

    【讨论】:

    • 这是错误的,有两个原因。没有为程序集定义方法,当方法不带参数时,应指定null。编辑:仍然考虑传递null,因为这是文档所述。
    • @Matthew 我知道,也许我必须更详细地解释一下。
    【解决方案4】:

    MethodInfo 有一个名为 Invoke 的方法。 因此,只需使用您创建的对象调用 Method.Invoke(),例如调用 System.Activator.CreateInstance()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多