如何实例化在 C# DLL 中声明的类?

发布于 2025-01-08 05:44:04 字数 1302 浏览 1 评论 0原文

我有一个用 C# 编写的 DLL。在此 DLL 中定义了一个类。 我们假设这个 DLL 的代码是:

namespace unloadableDLL
{
    public class DivisionClass
    {
        public /*static*/ long Division(long x, long y)
        {
            // We deliberately do not use a try catch to catch divide by 0 exceptions
            return (x / y);
        }
    }
}

现在,我想在测试程序中动态加载这个 DLL。我需要看看如果在以下两种情况下除以零会发生什么: 1)直接加载DLL(不使用AppDomain) 2)DLL不是直接加载的,而是先创建一个AppDomain,然后加载DLL。

我对 C# 完全陌生,我所说的“新”是指我刚开始工作不到 4 小时,但我有 C++ 背景。

我的问题是,在我的测试程序中,我需要实例化一个 DivisionClass 对象,但这个对象仅在 DLL 中声明。 =>已解决

我的测试程序是

class Program
    {
        [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
        static void Main(string[] args)
        {
            // Load the DLL
            Console.WriteLine("Attempting to load unloadableDLL");
            Assembly a = Assembly.LoadFrom("./unloadableDLL.dll");
            unloadableDLL.DivisionClass divisionObject = (unloadableDLL.DivisionClass)a.CreateInstance("unloadableDLL.DivisionClass");
            long number = divisionObject.Division(8, 2);
            Console.WriteLine(number);
        }
    }

我不知道是什么,但编译器一直告诉我静态成员 unloadableDLL.DivisionClass.Division(lon, long) 无法通过实例引用访问;相反,用类型名来限定它。

谢谢大家

I have a DLL written in C#. In this DLL there is a class that is defined.
Let's assume that the code of this DLL is :

namespace unloadableDLL
{
    public class DivisionClass
    {
        public /*static*/ long Division(long x, long y)
        {
            // We deliberately do not use a try catch to catch divide by 0 exceptions
            return (x / y);
        }
    }
}

Now, I want to load dynamically this DLL in a test program. I need to see what happens if I divide by zero in the two following cases :
1) DLL is loaded directly (without using an AppDomain)
2) DLL is not loaded directly, an AppDomain is created first and then it loads the DLL.

I'm completely new in C#, by new I mean I've started less than 4 hours ago but I have a C++ background.

My problem is that in my test program, I need to instanciate a DivisionClass Object but this one is declared only in the DLL.
=> Resolved

My test program is

class Program
    {
        [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
        static void Main(string[] args)
        {
            // Load the DLL
            Console.WriteLine("Attempting to load unloadableDLL");
            Assembly a = Assembly.LoadFrom("./unloadableDLL.dll");
            unloadableDLL.DivisionClass divisionObject = (unloadableDLL.DivisionClass)a.CreateInstance("unloadableDLL.DivisionClass");
            long number = divisionObject.Division(8, 2);
            Console.WriteLine(number);
        }
    }

I don't know what but the compilers keeps telling me that Static member unloadableDLL.DivisionClass.Division(lon, long) cannot be accessed with an instance reference; qualify it with a typename instead.

Thank you all

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光是把杀猪刀 2025-01-15 05:44:04

要加载到单独的 AppDomain 并从那里执行方法 - 使用反射,如以下 StackOverflow 问题。它确实涉及到通常更高级的 C# 主题,但代码相当样板,对于具有 C++ 知识的人来说,它不应该出现问题。

对于直接调用,请遵循上面概述的方法 - 即引用项目中的 dll 并根据 Oded 通过代码实例化(不幸的是,他删除了他的答案,因此在下面复制)

DivisionClass.Division(1, 2)

编辑

如果方法不是静态的

通过反射调用方法

  Assembly myAssembly1 = Assembly.LoadFrom("myPath\\Assembly1.dll");     
  Type myType = myAssembly1.GetType("MyClass");      
  object myObject = Activator.CreateInstance(myType);     
  myType.Invoke("myMethodName", BindingFlags.InvokeMethod, null, myObject, null); 

在单独的应用程序域中 会增加复杂性 - 请参阅 链接

另外,我认为您的部门课程不会按原样进行。要跨应用程序域调用,您需要对您的类采用某种序列化或从 MarshalByRefObject 继承该类 - 请参阅此 所以问题。鉴于这看起来像是概念类型的事物/类的基础实现,那么 MarshalByRefObject 将是您最好的选择 - 我认为最简单。也就是说,跨 AppDomain 执行可能会变得很麻烦。

通过代码中的实例化调用方法

DivisionClass divisor = new DivisionClass()
divisor.Division(1,2)

To load into a separate AppDomain an execute the method from there - use reflection as in the following StackOverflow question. It does get involved as is typically a more advanced C# topic but the code is fairly boilerplate and for a man with C++ knowledge it shouldn't present problems.

For a direct call then follow the methods outlined above - i.e. reference the dll in your project and instantiate through code as per Oded (who has deleted his answer unfortunately so reproducing below)

DivisionClass.Division(1, 2)

EDIT

If the methods are not static

Invoking a method via reflection

  Assembly myAssembly1 = Assembly.LoadFrom("myPath\\Assembly1.dll");     
  Type myType = myAssembly1.GetType("MyClass");      
  object myObject = Activator.CreateInstance(myType);     
  myType.Invoke("myMethodName", BindingFlags.InvokeMethod, null, myObject, null); 

In a separate App Domain adds to the complexity - see link.

Also I don't think your Division class will work as is. To call across app domains you need to employ some kind of serialisation for your classes or inherit the class from MarshalByRefObject - see this SO question. Given that this looks like a proof of concept type of thing/a ground up implementation of your class then MarshalByRefObject would be you best bet - easiest i think. That said executing across AppDomains can get fiddly.

Invoking a method via instaniation in code

DivisionClass divisor = new DivisionClass()
divisor.Division(1,2)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文