如何从外部模块引用功能?

时间:2017-03-10 10:04:29

标签: c#

我想为自己的游戏创建一个简单的游戏引擎,我想让它支持脚本系统。

我将自己的脚本语言编译为C#代码,并构建为DLL模块,由主应用程序加载。但是,这里有几个问题。

  1. 如何在运行时链接已编译的DLL?

    我可以链接将与“参考”一起使用的模块。但我不知道如何以编程方式在运行时链接DLL。

  2. 如何使加载模块引用主应用程序的功能或变量等...

    加载模块(编译过的脚本)必须为了它的目的而调用主应用程序的成员(好吧,我不知道它是否正确表达...)。

  3. 如何解决这些问题?我希望用纯C#(或.NET Framework)解决这个问题,而不是外部库。

    谢谢!

2 个答案:

答案 0 :(得分:0)

  

如何在运行时链接已编译的DLL?

     

我可以链接将与"参考"一起使用的模块。但我不是   知道如何以编程方式在运行时链接DLL。

您应该使用反射从指定的文件夹动态加载DLL(作为插件)。可以找到示例herehere

  

如何使加载模块能够引用主应用程序的功能,或者   变量等...

     

已加载的模块(已编译的脚本)必须调用主应用程序   成员(嗯,我不知道它是否正确的表达......)   它的目的。

您应该针对框架的接口编写这些DLL的代码。而且你不要求插件调用你的框架,而你的框架应该调用它们。

答案 1 :(得分:0)

您的问题比代码相关更具架构性。

首先,编写一个转换器(将一种语言翻译成另一种语言的代码)是一项繁琐的任务。但是,动态编译C#很容易。你可以使用Roslyn。查看这篇文章,获得一个很棒的教程:http://www.tugberkugurlu.com/archive/compiling-c-sharp-code-into-memory-and-executing-it-with-roslyn

接下来是另一个问题。一旦你有了DLL,你就需要将它加载到你的主AppDomain中。它也非常容易。只需使用Assembly.Load(...)方法即可。以下是一些示例:https://msdn.microsoft.com/en-us/library/25y1ya39(v=vs.110).aspx但是您需要知道,一旦您将DLL加载到AppDomain中,您就无法卸载它。如果您不使用任何技巧,则会将DLL加载到应用程序的主AppDomain中。然后,当您更改DLL中的代码时,您将无法摆脱它。唯一的方法是关闭并再次启动应用程序。否则,您需要将DLL加载到单独的AppDomain中。

现在,如何引用应用程序功能。为此,您需要创建interface。在符合接口的类中编写应用程序函数,然后将此类的实例传递到您加载的其他类,并从动态加载的DLL中实例化。

如上所述加载DLL,没有任何用处。您需要从DLL创建类的实例。为此,您可以使用Activator.CreateInstance(...)。作为要创建的类的参数传递一个符合您上面创建的接口的类实例。供您参考,此软件开发模式称为" strategy"。