如何实例化在 C# DLL 中声明的类?
我有一个用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
要加载到单独的 AppDomain 并从那里执行方法 - 使用反射,如以下 StackOverflow 问题。它确实涉及到通常更高级的 C# 主题,但代码相当样板,对于具有 C++ 知识的人来说,它不应该出现问题。
对于直接调用,请遵循上面概述的方法 - 即引用项目中的 dll 并根据 Oded 通过代码实例化(不幸的是,他删除了他的答案,因此在下面复制)
编辑
如果方法不是静态的
通过反射调用方法
在单独的应用程序域中 会增加复杂性 - 请参阅 链接。
另外,我认为您的部门课程不会按原样进行。要跨应用程序域调用,您需要对您的类采用某种序列化或从 MarshalByRefObject 继承该类 - 请参阅此 所以问题。鉴于这看起来像是概念类型的事物/类的基础实现,那么 MarshalByRefObject 将是您最好的选择 - 我认为最简单。也就是说,跨 AppDomain 执行可能会变得很麻烦。
通过代码中的实例化调用方法
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)
EDIT
If the methods are not static
Invoking a method via reflection
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