【vc++精品源码栏目提醒】:网学会员为广大网友收集整理了,易语言手册 - 艺术,希望对大家有所帮助!
版本:1.0作者:明日期:2010 年元月综述易语言静态编译技术手册,主要介绍易语言静态编译方案,以及支持库改造方法。
易语言 5.0“基于第三方链接器的”静态编译
方案的核心是:把易语言编译器生成的中间数据,编译成 COFF 格式的 obj 文件,然后把它交给第三方链接器,与各支持库的静态库(.lib文件)一起链接生成 EXE/DLL。
为了配合静态编译,易语言编译器、核心支持库、集成开发环境IDE均已做出重大更新,绝大多数官方支持库已完成自身改造。
第三方支持库需要作者按照本文介绍的方法完成支持库改造,以便支持静态编译。
未经静态编译改造的原有支持库,仍可在新版易语言中使用,只是不能支持静态编译。
支持库静态编译改造目的:使该支持库可以支持静态编译途径:1、在原支持库.fne基础上额外输出部分信息;2、提供支持库的静态库,并按要求导出特定的函数符号为了支持静态编译,对支持库框架做了扩展性修改,这种修改不会对现有的支持库造成任何负面影响。
即:如果不需要支持静态编译,现有的支持库不需要做任何修改;如果已经做了修改,也不影响原有功能和使用方式。
最大程度的保持支持库的向前向后兼容性。
今后支持库要分为两个版本:一个动态库版(即现有的 fne/fnr 等),一个静态库版。
动态库版支持库,除了提供向后兼容的运行时支持外,还要在静态编译连接期间提供数据支持。
静态库版支持库,用于静态编译连接,编译连接期间需要动态库版支持库的支持,但编译连接后生成的 EXE/DLL 不依赖任何非系统库。
动态库版和静态库版,基本上还是使用同一套源代码,只是在必要的地方用 C/C预定义宏(__E_STATIC_LIB)区分。
以下说明中将明确区分静态库和动态库。
为支持静态编译,易语言支持库开发包接口文件 lib2.h 中增加了以下通知项(系统发送给 :支持库的通知 PFN_NOTIFY_LIB)define NL_GET_CMD_FUNC_NAMES 14 // 返回所有命令实现函数的的函数名称数组char 支持静态编译的动态库必须处理define NL_GET_NOTIFY_LIB_FUNC_NAME 15 // 返回处理系统通知的函数名称PFN_NOTIFY_LIB 函数名称 支持静态编译的动态库必须处理define NL_GET_DEPENDENT_LIBS 16 // 返回静态库所依赖的其它静态库文件名列表格式为0 分隔的文本结尾两个0支持静态编译的动态库必须处理 // kernel32.lib user32.lib gdi32.lib 等常用的系统库不需要放在此列表中 // 返回 NULL 或 NR_ERR 表示不指定依赖文件为了支持静态编译,支持库必须做出的改动,详述如下。
示例请参考易语言安装目录 sdk一、部分函数需要修改函数名称和符号导出方式所有命令和方法的实现函数PFN_EXECUTE_CMD、处理
系统通知的函数PFN_NOTIFY_LIB, 均 ,并修改为以 C 符号形式导出(在 C中使用 extern需要修改函数名称,添加“库名称前缀”C);所 有 数 据 类 型 的 接 口 获 取 函 数 PFN_GET_INTERFACE , 需 要 统 一 命 名 为 库 名 称 前缀_GetInterface_, 并修改为以 C 符号形式导出 (在 C中使用 externC);非窗口组件数据类型不需要接口获取函数。
这些改动,对静态库来说是必须的,对动态库来说是可有可无的。
考虑到两者使用同一套源代码,可统一修改,以减少分开维护的成本。
上面提到的“库名称前缀”,是指其所在支持库(动态库)的文件名的全小写形式,不包含路径和文件名后缀。
以核心库 krnln.fne 为例,其库名称前缀就是 krnln 。
注意,库名称前缀一定是全部小写字母、数字和下划线的组合,且不能以数字开头,如果库名称确实是以数字开头的,请在库名称前缀前加下划线。
对于文件名中有汉字的支持库,其库名称前缀应是,下划线加上库文件名的 UTF-8 编码的十六进制文本全小写形式(如支持库“汉字.fne”的库 。
名称前缀为 _e6b189e5ad97) 但目前静态编译版本暂不支持有汉字的支持库文件名, 和以数字开头的支持库文件名。
修改示例:假 设 之 前 的 核 心 支 持 库 中 有 一 个 命 令 的 实 现 函 数 是 这 么 定 义 的 : void fnMessageBoxPMDATA_INF pRetData INT nArgCount PMDATA_INF pArgInf修 改 之 后 应 该 是 : extern C void krnln_fnMessageBox PMDATA_INF pRetData INTnArgCount PMDATA_INF pArgInf假设之前的核心支持库中有一个数据类型的接口获取函数是这么定义的:PFN_INTERFACEWINAPI Button_GetInterface INT nInterfaceNO修改之后应该是:extern C PFN_INTERFACE WINAPI krnln_GetInterface_Button INTnInterfaceNO为减少修改工作量,可定义类似如下的 C/C宏(注意把 XXX 和 xxx 替换为自已的库名称前缀):ifdef __cplusplus define EXTERN_C extern Celse define EXTERN_Cendifdefine DEFINE_XXX_EXECUTE_CMDfnName EXTERN_C void xxx_fnName PMDATA_INF pRetData INT nArgCount PMDATA_IN