⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ef.h

📁 易语言IDE源代码
💻 H
📖 第 1 页 / 共 5 页
字号:
/*
    版权所有 (C) 2007 大连大有吴涛易语言软件开发有限公司

    在满足下列所有许可条件的前提下,允许以源代码形式或编译后形式使用或重新发布本源文件的未经修改版本或修改后版本:
    1、如果以源代码形式重新发布,必须完整保留作者版权声明。
    2、如果以编译后形式重新发布,必须在发布版本的文档中重申作者版权声明。
    3、如果重新发布修改后版本,必须注明修改内容,必须完整保留或重申原作者版权声明。
    4、对本源文件的任何使用,必须满足以下要求之一:
       A、开发“易语言.飞扬”类库;
       B、开发用于“易语言.飞扬”的工具软件;
       C、开发用作辅助已有“易语言.飞扬”程序的软件。
    5:本源文件的作者不作任何承诺。任何情况下因任何原因而导致的任何损害,均不承担任何责任。
    6:必须保证本协议的完整性。
*/


#ifndef __EF_H__
#define __EF_H__

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#include <ef/types.h>
#include <ef/hashmap.h>
#include <ef/functions.h>


////////////////////////////////////////////////////////////////////////////////

// EFL, EF Library
#define EF_EFL_FILE_EXT  myT(".efl")  // 使用“易语言.飞扬”自身开发的EF类库文件名后缀

// EFN, EF Native library
#define EF_EFN_FILE_EXT  myT(".efn")  // 使用C++等其它编程语言开发的的EF类库文件名后缀

// 所有EF本地类库都必须导出的函数名称及其原型
#define EF_GET_LIB_INFO_FUNC_EXPORT_NAME    "EF_GetLibInfo"
#define EF_GET_LIB_INFO_FUNC_EXPORT_NAME_W  myT("EF_GetLibInfo")

struct EFLibInfo;
typedef EFLibInfo* (*EF_PFN_GET_LIB_INFO) ();

// 指定EF类库加载路径的系统环境变量名称
#define EF_LIB_PATHS_NAME    "EF_LIB_PATHS"
#define EF_LIB_PATHS_NAME_W  myT("EF_LIB_PATHS")

////////////////////////////////////////////////////////////////////////////////

typedef struct _tagEFVirtualTableItem
{
    // 记录当前类方法进行了虚拟覆盖处理后的方法地址,因此本方法地址可能指向其继承类中的覆盖方法地址。
    EF_PFUNC m_pfnCurrent;
    // 记录当前类方法定义时所提供的方法地址
    EF_PFUNC m_pfnOld;
}
EFVirtualTableItem;

struct EFClassInfo;

typedef struct _tagEFSingleObjectRuntimeInfo
{
    EFClassInfo* m_pClassInfo;
    // 所指向的是一个EFVirtualTableItem数组,顺序记录m_pClassInfo和其实现的接口中定义的所有虚函数(非私有/非静态)方法地址,
	// 记录顺序为:类自身的方法,类所实现接口的方法。
    EFVirtualTableItem* m_pVirtualFuncTable;
}
EFSingleObjectRuntimeInfo;

typedef struct _tagEFObjectRuntimeInfo
{
    EFInt m_nClassCount;
    // 下面顺序记录从最基础类到当前对象类的信息。
    EFSingleObjectRuntimeInfo m_aryInfos [1 /*m_nClassCount*/];
}
EFObjectRuntimeInfo;

struct EFObject
{
    EFDWord m_dwRefCount;  // 本对象的被引用计数和类型
    EFObjectRuntimeInfo* m_pObjectInfo;  // 本对象的运行时类型信息
    // 下面顺序记录从最基础类到当前对象类的类数据。
    void* m_paryData [1 /*m_pObjectInfo->m_nClassCount*/];
};
typedef struct EFObject EFObject;

struct EFInterfaceInfo;

typedef struct _tagEFInterface
{
    EFDWord m_dwRefCount;  // 本接口对象的被引用计数和类型
    EFObject* m_pObject;   // 本接口所参考到的对象数据
    EFVirtualTableItem* m_pInterfaceFuncs;  //   该接口的实现方法地址表,注意是从其最基础接口方法表开始顺序记录。
                                            // 注意EFVirtualTableItem中的m_pfnOld在此没有意义。
    EFInterfaceInfo* m_pInterfaceInfo;      // 接口定义信息
}
EFInterface;

/*
对象数据格式实例剖析:

    假设存在以下类和接口定义:

         接口 接口1
         {
             接口1_方法1 ();
             接口1_方法2 ();
         }

         接口 接口2 <基接口 = "接口1">
         {
             接口2_方法1 ();
         }

         接口 接口3
         {
             接口3_方法1 ();
         }

         类 类1 <接口实现表 = " 接口3, 接口2">
         {
             接口1_方法1 ()  { }
             接口1_方法2 ()  { }
             接口3_方法1 ()  { }
             接口2_方法1 ()  { }

             类1_方法1 ()  { }
             方法2 ()  { }

             整数 类1_数据1;
             整数 类1_数据2;
         }

         类 类2 <基类 = "类1">
         {
             类2_方法1 ()  { }
             方法2 ()  { }

             整数 类2_数据1;
         }         

    那么,假设存在语句:

        类2 abc = 创建 类2;

    此语句执行后 abc 对象数据 EFObject 结构的各成员值具体为:

        m_dwRefCount   = 1               // 新创建出来对象实例的 m_nRefCount 将被初始化为 1
        m_pObjectInfo = 类2_pObjectInfo  // 指向类2的运行时信息
        m_paryData =
            类1_pData,  // 指向对象中类1部分的数据
            类2_pData   // 指向对象中类2部分的数据

    类1_pData 指针所指向的数据区域为两个整数,分别为“类1_数据1”和“类1_数据2”的具体运行时值。
    类2_pData 指针所指向的数据区域为一个整数,为“类2_数据1”的具体运行时值。

    类2_pObjectInfo 所指向的是一个 EFObjectRuntimeInfo 结构,其各成员值具体为:
    
        m_nClassCount = 2   // 包括基础类在内共两个类(在此忽略掉系统默认的所有类共有最基础类)
        m_aryInfos =
            类1_pSingleObjectRuntimeInfo,  // 指向类1的运行时定义数据
            类2_pSingleObjectRuntimeInfo   // 指向类2的运行时定义数据

    类1_pSingleObjectRuntimeInfo 所指向的是一个 EFSingleObjectRuntimeInfo 结构,其各成员值具体为:
    
        m_pClassInfo 指向“类1”的类定义信息。
        m_pVirtualFuncTable 指向的数据区顺序记录类1的所有非私有和静态成员方法代码地址,具体为:

        // 首先记录类本身不在接口中的成员方法:

            { 类1_方法1,  类1_方法1 },
            { 方法2(由于本方法被类2覆盖,所以它指向类2中“方法2”实现代码地址),  方法2(记录类1中本来的“方法2”实现代码地址) },

        // 然后顺序记录类所实现的每个接口的成员方法,如果某个接口具有基接口,先记录其基接口的成员方法:

            { 接口3_方法1, 接口3_方法1 },

            { 接口1_方法1, 接口1_方法1 },
            { 接口1_方法2, 接口1_方法2 },
            { 接口2_方法1, 接口2_方法1 },

    类2_pSingleObjectRuntimeInfo 所指向的是一个 EFSingleObjectRuntimeInfo 结构,其各成员值具体为:

        m_pClassInfo 指向“类2”的类定义信息。
        m_pVirtualFuncTable 顺序记录类2的所有非私有和静态成员方法代码地址,具体为:

            { 类2_方法1,  类2_方法1 },
            { 方法2(类2中“方法2”实现代码地址,后同),  方法2 },
*/

// nIndex: 0、1、2 ..... ,按照从当前类到其最基础类的顺序。
#define EF_GET_SPEC_CLASS_INFO(pObject, nIndex)  \
	(((EFObject*)pObject)->m_pObjectInfo->m_aryInfos [((EFObject*)pObject)->m_pObjectInfo->m_nClassCount - 1 - nIndex].m_pClassInfo)

#define EF_GET_CLASS_INFO_BY_INDEX(pObject, nClassIndex)  \
	(((EFObject*)pObject)->m_pObjectInfo->m_aryInfos [nClassIndex].m_pClassInfo)

#define EF_GET_CLASS_INFO(pObject)  \
	EF_GET_SPEC_CLASS_INFO(pObject, 0)

////////////////////////////////////////////////////////////////////////////////

struct EFLibInfo;

/*
扩展属性表m_szExtendedPropertyList说明:
    1、属性表格式: 为类似"属性名 属性名=属性值 ..."的文本, 各扩展属性之间用空格分开。
    2、属性值可以为文本、逻辑值、数值。
    3、数值型属性值可以为二进制(0B开头)、十六进制(0X开头)、十进制数值,比如:
         长度 = 0x123
         长度 = 0b10101
         长度 = 123
    4、文本型属性值用双引号括住,中可以包含转义符,具体支持的转义符及其含义如下:
        \t          制表符
        \r          回车符
        \n          换行符
        \\          \
        \"          "
        \'          '
        \x????      ?为十六进制字符,用作具体提供某个字符的十六进制码值
    5、可以省略文本型属性值两端的双引号,但此时有以下要求:
        A、文本值必须为一个有效的易语言名称或一组使用','或'.'号连接起来的易语言名称,且其中不能包含转义符;
        B、','和'.'将被认为是文本的一部份,如: “名称 = sys.object”,“列表 = p1,p2,p3”等。
           ','或'.'号后必须跟一个有效名称,如"列表 = p1,,p3”将是错误的,因为第二个逗号后没有跟一个有效名称。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -