solomn517 Ответов: 2

Как вызвать метод из библиотеки dll с помощью отражения


dll-файл, содержащий метод, файл проекта, вызывающий метод в dll, исключение и мои выводы приведены ниже, я не понимаю, чего мне не хватает. Пожалуйста, помогите!

DLL-файл:
public class Class2
    {
        public string TestMethod1()
        {
            return "hello world!";
        }

        public void TestMethod2(int test)
        {
        }
    }

Проект, в котором вызывается метод в dll:
try
            {
                Assembly assembly = Assembly.LoadFrom(@"D:\TestDll.dll");                
                foreach (Type ti in assembly.GetTypes().Where(x => x.IsClass))
                {
                    if (ti.Name == "Class2")
                    {
                        ti.GetMethod("TestMethod2");
                        MethodInfo[] method = ti.GetMethods();
                        Type t = assembly.GetType("TestDll.Class2");
                        BindingFlags flags = BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance;
                        object res = t.InvokeMember("TestMethod2", BindingFlags.InvokeMethod, null, t, new object[0]);
                    }
                }
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
            }

Исключение:
MissingMethodException Occurred<br />
Method 'TestDll.Class2.TestMethod2' not found.


Мои выводы из MethodInfo:
method[1] = {Void TestMethod2(Int32)};<br />
method[1].Name = TestMethod2


Если я изменяю последний параметр т. е. входные параметры возникает следующая ошибка
Исключение:
TargetException Occurred<br />
Object does not match target type.

2 Ответов

Рейтинг:
16

Karthik_Mahalingam

Попробуй вот так..


if (ti.Name == "Class2")
           {
               MethodInfo TestMethod1 = ti.GetMethod("TestMethod1");
               MethodInfo TestMethod2 = ti.GetMethod("TestMethod2");
               var instance = Activator.CreateInstance(ti);
               string value = TestMethod1.Invoke(instance, null).ToString();
               TestMethod2.Invoke(instance, new object[] { 1 });

           }


solomn517

Спасибо, Картик! Он работает, есть идеи, как вызвать метод из библиотеки dll интерфейса? Я считаю, что экземпляр не может быть создан для интерфейса.

Karthik_Mahalingam

добро пожаловать Соломон :)
да ты можешь
проверить это ссылка

solomn517

Я этого совсем не понимаю, Картик :'(
можете ли вы объяснить, используя код, который я дал выше.
Предположим, что класс Class2 реализует интерфейс, который имеет 2 метода, и Class2 содержит определение для обоих методов, объявленных в интерфейсе, т. е. Testmethod 1 & Testmethod 2.
Как бы я теперь вызвал интерфейсную dll?

Karthik_Mahalingam

это бесполезно, как бы вам ни понадобился экземпляр класса, реализующего интерфейс...
так что интерфейс не будет приходить на картинку.
понял ??

solomn517

да.. спасибо, Картик!

Karthik_Mahalingam

добро пожаловать :)

Member 11964881

Спасибо, что сработало. Вы можете найти подробное объяснение доступа к свойствам и методам с помощью отражения в C# здесь

Karthik_Mahalingam

добро пожаловать

Рейтинг:
1

OriginalGriff

Просто: ваши методы не статичны, они являются методами экземпляра: вам нужно создать экземпляр объекта и передать его через него, а не пытаться передать тип класса, и вам нужно передать аргумент через него:

Assembly assembly = Assembly.LoadFrom(@"D:\TestDll.dll");
foreach (Type ti in assembly.GetTypes().Where(x => x.IsClass))
    {
    if (ti.Name == "Class2")
        {
        Type t = assembly.GetType("TestDll.Class2");
        object obj = t.InvokeMember(null,
                                    BindingFlags.DeclaredOnly |
                                       BindingFlags.Public |
                                       BindingFlags.NonPublic |
                                       BindingFlags.Instance |
                                       BindingFlags.CreateInstance,
                                    null,
                                    null,
                                    null);
        object res = t.InvokeMember("TestMethod2", BindingFlags.InvokeMethod, null, obj, new object[] { (object)13 });
        }
    }