developer tip

C #에서 런타임에 DLL로드

copycodes 2020. 10. 21. 08:14
반응형

C #에서 런타임에 DLL로드


C # 응용 프로그램 내에서 런타임에 .dll을 가져오고 사용하는 방법을 알아 내려고 노력 중입니다. Assembly.LoadFile ()을 사용하여 내 프로그램이 dll을로드하도록 관리했습니다 (이 부분은 ToString ()으로 클래스 이름을 가져올 수 있으므로 확실히 작동합니다). 그러나 '출력'을 사용할 수 없습니다. 내 콘솔 응용 프로그램 내부에서 메서드. .dll을 컴파일 한 다음 콘솔의 프로젝트로 옮깁니다. CreateInstance와 메서드를 사용할 수있는 사이에 추가 단계가 있습니까?

이것은 내 DLL의 클래스입니다.

namespace DLL
{
    using System;

    public class Class1
    {
        public void Output(string s)
        {
            Console.WriteLine(s);
        }
    }
}

여기에 DLL을로드하려는 응용 프로그램이 있습니다.

namespace ConsoleApplication1
{
    using System;
    using System.Reflection;

    class Program
    {
        static void Main(string[] args)
        {
            var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

            foreach(Type type in DLL.GetExportedTypes())
            {
                var c = Activator.CreateInstance(type);
                c.Output(@"Hello");
            }

            Console.ReadLine();
        }
    }
}

C #에서 직접 호출하려면 컴파일 타임에 멤버를 확인할 수 있어야합니다. 그렇지 않으면 반사 또는 동적 개체를 사용해야합니다.

반사

namespace ConsoleApplication1
{
    using System;
    using System.Reflection;

    class Program
    {
        static void Main(string[] args)
        {
            var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

            foreach(Type type in DLL.GetExportedTypes())
            {
                var c = Activator.CreateInstance(type);
                type.InvokeMember("Output", BindingFlags.InvokeMethod, null, c, new object[] {@"Hello"});
            }

            Console.ReadLine();
        }
    }
}

동적 (.NET 4.0)

namespace ConsoleApplication1
{
    using System;
    using System.Reflection;

    class Program
    {
        static void Main(string[] args)
        {
            var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

            foreach(Type type in DLL.GetExportedTypes())
            {
                dynamic c = Activator.CreateInstance(type);
                c.Output(@"Hello");
            }

            Console.ReadLine();
        }
    }
}

Right now, you're creating an instance of every type defined in the assembly. You only need to create a single instance of Class1 in order to call the method:

class Program
{
    static void Main(string[] args)
    {
        var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

        var theType = DLL.GetType("DLL.Class1");
        var c = Activator.CreateInstance(theType);
        var method = theType.GetMethod("Output");
        method.Invoke(c, new object[]{@"Hello"});

        Console.ReadLine();
    }
}

You need to create an instance of the type that expose the Output method:

static void Main(string[] args)
    {
        var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

        var class1Type = DLL.GetType("DLL.Class1");

        //Now you can use reflection or dynamic to call the method. I will show you the dynamic way

        dynamic c = Activator.CreateInstance(class1Type);
        c.Output(@"Hello");

        Console.ReadLine();
     }

Activator.CreateInstance() returns an object, which doesn't have an Output method.

It looks like you come from dynamic programming languages? C# is definetly not that, and what you are trying to do will be difficult.

Since you are loading a specific dll from a specific location, maybe you just want to add it as a reference to your console application?

If you absolutely want to load the assembly via Assembly.Load, you will have to go via reflection to call any members on c

Something like type.GetMethod("Output").Invoke(c, null); should do it.


It's not so difficult.

You can inspect the available functions of the loaded object, and if you find the one you're looking for by name, then snoop its expected parms, if any. If it's the call you're trying to find, then call it using the MethodInfo object's Invoke method.

Another option is to simply build your external objects to an interface, and cast the loaded object to that interface. If successful, call the function natively.

This is pretty simple stuff.

참고URL : https://stackoverflow.com/questions/18362368/loading-dlls-at-runtime-in-c-sharp

반응형