代码之家  ›  专栏  ›  技术社区  ›  MartyIX

如何在C中正确地实现插件?

  •  9
  • MartyIX  · 技术社区  · 15 年前

    我正在尝试向我的游戏添加插件,我要实现的是:

    • 插件要么是我的,要么是第三方的,所以我想要一个解决方案,插件崩溃并不意味着主应用程序崩溃。

    • 插件的方法经常被调用(例如因为绘制游戏对象)。

    到目前为止我所发现的:

    你能评论一下我的发现吗?新方法也受到欢迎!谢谢!

    4 回复  |  直到 15 年前
        1
  •  10
  •   Jasper    15 年前

    您可以定义插件必须实现的公共接口。然后,通过使用反射,您可以扫描“plugin”文件夹中实现该接口的任何类,然后创建该类的实例。

    从你的代码来看,只要在接口上工作并调用所需的方法就行了。关于崩溃,一定要确保对“plugin”接口的调用总是封装在一个try/catch块中。如果发生异常,您可以始终释放插件

        2
  •  2
  •   ligos    15 年前

    我怀疑你有两个要求:

    1. 使用图形对象和
    2. 插件崩溃不会使你的应用崩溃

    将会发生冲突。

    为了真正确保一个bugy插件不会使你的应用崩溃,你必须将它加载到一个单独的AppDomain中(正如你已经确定的那样)。但是,您将受到性能影响,因为AppDomain的关键是它们隔离对象的实例。因此,您至少需要将参数序列化到插件(可能使用MarshalByRef对象或远程处理)。我怀疑这意味着将你的游戏状态中的一大块串联起来(听起来至少包含了某种图像)。另一方面,AppDomain生活在相同的进程空间中,因此开销没有跨进程通信那么严重。

    卸载插件和卸载AppDomain一样简单。

    因为您必须对参数进行序列化,所以您可以在插件处理后验证您的游戏状态。

    我曾经玩过AppDomain。根据我的经验,建造一个需要几秒钟。这可能会影响您加载到每个AppDomain中的插件数量。

        3
  •  1
  •   M.A. Hanin    15 年前

    .NET扩展性的通用“secrect”是:动态加载(将插件放入AppDomain)、反射(验证它是否支持您指定的方法/接口)、属性(获取版本控制之类的元数据)、后期绑定(实际使用插件)。

    如果您的扩展性需求非常简单或非常独特,那么您应该考虑以自己的方式实现它。

        4
  •  1
  •   Spooky Muscothym    10 年前

    我用过 this tutorial 作为几年前我自己插件架构的基础。我认为,我的体系结构相对简单,但在插件之间传递消息时遇到了一些问题。

    如果你打算写自己的架构,那就足够公平了,但我会警告你不要这样做。这不是一个小任务,迟早你会遇到一些主要的设计考虑,比如消息传递,这些都是需要解决的重要问题(如果公认的同时非常有趣和令人沮丧的话)。使用像MEF这样的东西可以为您解决这些问题,并提供一个非常好的API和框架来构建插件,这是非常有价值的。

    此外,MEF最终将作为应用程序的一部分进行分发,因此您不需要让用户单独下载;就他们而言,它是一种“不可见”的依赖关系,对于开发人员(包括您自己)来说,它是一种轻量的依赖关系。它也是Visual Studio 2010的官方插件体系结构,因此它在.NET社区中有很大的影响力,如果您也使用它,那么只有更多的开发人员能够为您的应用程序编写插件。

    希望这有点道理。