zoukankan      html  css  js  c++  java
  • 转:自己动手写插件框架(3)

    转自:http://www.devbean.net/2012/03/building-your-own-plugin-framework-3/

    编程语言的支持

    在前面的章节中,我们已经了解到,如果你能够使用编译器令应用程序和插件的虚表匹配,那么就可以保持 C++ 虚表级别的兼容性;或者你可以使用 C 级别的兼容性,然后就能使用不同的编译器去构建系统,但其限制在于你只能编写纯 C 应用。这样的话,你就不能够使用前面我们在例子 IActor 中看到的那种优雅的 C++ 接口。

    纯 C 实现

    在纯 C 的编程模型中,你只能使用 C 开发插件。当实现PF_CreateFunc函数时,需要返回一个 C 对象同应用程序的 C 对象模型进行交互。

    但是,我们知道,C 语言是一个过程语言,没有对象的概念。那么,刚刚提到的 C 对象和 C 对象模型是怎么回事呢?为了理解这一点,我们必须认识到,C 语言已经提供了足够多的抽象机制来实现对象、引入多态(这一点在我们的插件框架中尤其重要)以及支持面向对象风格的编程。事实上,原始的 C++ 编译器就是一个 C 编译器的前端。它将 C++ 代码翻译成 C 代码,然后直接输出给一个普通的 C 编译器(当然,我们说的是“原始的”C++ 编译器)。它的名字就叫 Cfront 这已经足够说明问题了。

    核心技术是,使用包含函数指针的结构体。每个函数声明的第一个参数都应该是指向本结构体的指针。这个结构体也可能包含其他数据成员。也就是说,我们使用结构体模拟了 C++ 的类,提供了封装(在一个地方保存状态和行为)、继承(通过将父结构体作为第一个数据成员实现)和多态(通过设置不同的函数指针实现)。

    C 不支持析构函数、函数和运算符的重载以及命名空间,所以在定义接口时,我们能够设置的选项极为有限。这可能有点因祸得福,因为那些掌握了 C++ 语言不同子集的人们都明白使用接口,而不一定了解析构函数、运算符重载那些机制。减少接口的语言结构上的限制,有助于简化接口,提高可用性。

    在下面的章节中,我们将讨论面向对象的 C 语言设计。下面是我们的简单游戏的 C 对象模型的实现。如果你快速浏览一遍,你会发现它甚至支持集合类型和对象遍历器。

    C

     1 #ifndef C_OBJECT_MODEL
     2 #define C_OBJECT_MODEL
     3  
     4 #include <apr-1/apr.h>
     5  
     6 #define MAX_STR 64 /* max string length of string fields */
     7  
     8 typedef struct C_ActorInfo_
     9 {
    10     apr_uint32_t id;
    11     apr_byte_t   name[MAX_STR];
    12     apr_uint32_t location_x;
    13     apr_uint32_t location_y;
    14     apr_uint32_t health;
    15     apr_uint32_t attack;
    16     apr_uint32_t defense;
    17     apr_uint32_t damage;
    18     apr_uint32_t movement;
    19 } C_ActorInfo;
    20  
    21 typedef struct C_ActorInfoIteratorHandle_ { char c; } * C_ActorInfoIteratorHandle;
    22 typedef struct C_ActorInfoIterator_
    23 {
    24   void (*reset)(C_ActorInfoIteratorHandle handle);
    25   C_ActorInfo * (*next)(C_ActorInfoIteratorHandle handle);
    26  
    27   C_ActorInfoIteratorHandle handle;
    28 } C_ActorInfoIterator;
    29  
    30 typedef struct C_TurnHandle_ { char c; } * C_TurnHandle;
    31 typedef struct C_Turn_
    32 {
    33   C_ActorInfo * (*getSelfInfo)(C_TurnHandle handle);
    34   C_ActorInfoIterator * (*getFriends)(C_TurnHandle handle);
    35   C_ActorInfoIterator * (*getFoes)(C_TurnHandle handle);
    36  
    37   void (*move)(C_TurnHandle handle, apr_uint32_t x, apr_uint32_t y);
    38   void (*attack)(C_TurnHandle handle, apr_uint32_t id);
    39  
    40   C_TurnHandle handle;
    41 } C_Turn;
    42  
    43 typedef struct C_ActorHandle_ { char c; } * C_ActorHandle;
    44 typedef struct C_Actor_
    45 {
    46     void (*getInitialInfo)(C_ActorHandle handle, C_ActorInfo * info);
    47     void (*play)(C_ActorHandle handle, C_Turn * turn);
    48  
    49     C_ActorHandle handle;
    50 } C_Actor;
    51  
    52 #endif

    纯 C++ 实现

    在纯 C++ 编程模型中,你需要使用 C++ 开发插件。插件的接口函数可以由 static 成员函数实现,或者是普通的 static、全局函数(毕竟,C++ 简单来说就是 C 的超集)。此时,我们的对象模型就可以是普通 C++ 对象模型。下面的代码是同一游戏的 C++ 对象模型的实现。它和前面的 C 对象模型几乎是一样的。 

  • 相关阅读:
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    block的是发送信号的线程,又不是处理槽函数的线程
  • 原文地址:https://www.cnblogs.com/kira2will/p/3943932.html
Copyright © 2011-2022 走看看