易语言支持库制作学习笔记.doc_第1页
易语言支持库制作学习笔记.doc_第2页
易语言支持库制作学习笔记.doc_第3页
易语言支持库制作学习笔记.doc_第4页
易语言支持库制作学习笔记.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

易语言支持库制作学习笔记 本文讲讲用VS2008制作易语言支持库(动态库和静态库)的具体方法和步骤。这是我学习制作支持库时的操作步骤和学习笔记,贴出来分享下,也方便我以后查询。时间仓促水平有限,不到之处还请各位高手们批评指正,以便完善。本文欢迎转载,但请注明作者和出处。谢谢!易语言支持库制作顺序是先制作动态库(dll) 再制作静态库(lib)。I. 动态库的制作1. 打开VS2008, 新建项目MFC DLL, 名称mylib, 完成2. 项目属性,配置里选择所有配置 (设置debug和release模式的配置项)项目属性 - 常规 - 字符集 设置为多字节字符集 项目属性 - C+选项卡 - 附加包含目录 填入sdk的Elib目录,如我的Elib目录是 D:E51sdkcppELib3. 编写代码1. 打开mylib.cpp文件2. 文件头处加入#include #include #include #include 3.文件结尾处加入自己的代码1) 定义LIB_INFO这段代码是定义模块信息的,只在动态模块中使用,所以加入宏_E_STATIC_LIB来定义。也就是说,如果是静态库那么这段代码就不会被编译。静态库编译的时候只需在项目设置的C+ - 预处理器 中加入 _E_STATIC_LIB 即可。#ifndef _E_STATIC_LIBstatic LIB_INFO LibInfo =/* 库格式号, GUID串号, 主版本号, 次版本号, 构建版本号, 系统主版本号, 系统次版本号, 核心库主版本号, 核心库次版本号, 支持库名, 支持库语言, 支持库描述, 支持库状态, 作者姓名, 邮政编码, 通信地址, 电话号码, 传真号码, 电子邮箱, 主页地址, 其它信息, 类型数量, 类型指针, 类别数量, 命令类别, 命令总数, 命令指针, 命令入口, 附加功能, 功能描述, 消息指针, 超级模板, 模板描述, 常量数量, 常量指针, 外部文件 */LIB_FORMAT_VER, _T(LIB_GUID_STR), LIB_MajorVersion, LIB_MinorVersion, LIB_BuildNumber, LIB_SysMajorVer, LIB_SysMinorVer, LIB_KrnlLibMajorVer, LIB_KrnlLibMinorVer, _T(LIB_NAME_STR), _GBK_LANG_VER, _WT(LIB_DESCRIPTION_STR), _LIB_OS(_OS_WIN), _WT(LIB_Author), _WT(LIB_ZipCode), _WT(LIB_Address), _WT(LIB_Phone), _WT(LIB_Fax), _WT(LIB_Email), _WT(LIB_HomePage), _WT(LIB_Other), sizeof(DataTypes)/sizeof(DataTypes0), DataTypes, LIB_TYPE_COUNT, _WT(LIB_TYPE_STR), sizeof(Commands)/sizeof(Commands0), Commands, ExecuteCommand, NULL, NULL, mylib_ProcessNotifyLib, NULL, NULL, sizeof(Consts)/sizeof(Consts0), Consts, NULL;PLIB_INFO WINAPI GetNewInf()return (&LibInfo);#endif注意: GetNewInf 是易语言动态库 (dll) 唯一必须导出的函数。所以需要在.def文件里定义以下mylib.def里加入EXPORTS ; 此处可以是显式导出 GetNewInf接下来我们看看LIB_INFO 是如何定义的。具体含义可以在开发文档里察看。这里根据模块不同,需要修改的地方有1- LIB_ 这样的变量是我们另外定义的,可以定义在mylib.h中如下:#ifndef _E_STATIC_LIB#define LIB_GUID_STR 0000000000000000000000000000 /*GUID串: 00000000-0000-0000 必须使用guidgen.exe生成*/#define LIB_MajorVersion 1 /*库主版本号*/#define LIB_MinorVersion 1 /*库次版本号*/#define LIB_BuildNumber 20110318 /*构建版本号*/#define LIB_SysMajorVer 3 /*系统主版本号*/#define LIB_SysMinorVer 0 /*系统次版本号*/#define LIB_KrnlLibMajorVer 3 /*核心库主版本号*/#define LIB_KrnlLibMinorVer 0 /*核心库次版本号*/#define LIB_NAME_STR 支持库名称 /*支持库名*/#define LIB_DESCRIPTION_STR 支持库功能描述 /*功能描述*/#define LIB_Author 作者名称 /*作者名称*/#define LIB_ZipCode 邮政编码 /*邮政编码*/#define LIB_Address 通信地址 /*通信地址*/#define LIB_Phone 电话号码 /*电话号码*/#define LIB_Fax 传真号码 /*传真号码*/#define LIB_Email 电子邮箱 /*电子邮箱*/#define LIB_HomePage 主页地址 /*主页地址*/#define LIB_Other 其它信息 /*其它信息*/#define LIB_TYPE_COUNT 1 /*命令数量*/#define LIB_TYPE_STR 0000基本命令00 /*命令分类*/#endif2- DataTypes 是库中定义的数据类型,类型数量可以自动由sizeof(DataTypes)/sizeof(DataTypes0) 计算。Commands 命令类别,ExecuteCommand 命令指针,Consts 常量 都是一样的。这些都是库中希望定义的成员。如果不需要就在数量上写0,变量处替换成NULL即可。3- mylib_ProcessNotifyLib 是需要定义的消息指针。需要定义在宏的外面EXTERN_C INT WINAPI mylib_ProcessNotifyLib(INT nMsg, DWORD dwParam1, DWORD dwParam2)#ifndef _E_STATIC_LIB if(nMsg = NL_GET_CMD_FUNC_NAMES) / 返回所有命令实现函数的的函数名称数组(char*), 支持静态编译的动态库必须处理 return (INT)CommandNames; else if(nMsg = NL_GET_NOTIFY_LIB_FUNC_NAME) / 返回处理系统通知的函数名称(PFN_NOTIFY_LIB函数名称), 支持静态编译的动态库必须处理 return (INT)mylib_ProcessNotifyLib; else if(nMsg = NL_GET_DEPENDENT_LIBS) return (INT)NULL; / 返回静态库所依赖的其它静态库文件名列表(格式为0分隔的文本,结尾两个0), 支持静态编译的动态库必须处理 / kernel32.lib user32.lib gdi32.lib 等常用的系统库不需要放在此列表中 / 返回NULL或NR_ERR表示不指定依赖文件 #endifreturn ProcessNotifyLib(nMsg, dwParam1, dwParam2);本函数的作用是接收来自易语言IDE或者运行时环境的通知。并且在编译的时候起到在静态库和动态库之间通讯的目的。接下来我们就可以定义库中需要使用的函数,类型,常量 了。这些都定义在 mylib_ProcessNotifyLib 函数的前面,且都定义在宏中#ifndef _E_STATIC_LIB.#endif因为这些只需包含在动态模块里,不需要静态中定义。2) 定义常量 Consts#ifndef _E_STATIC_LIBLIB_CONST_INFO Consts = /* 中文名称, 英文名称, 常量布局, 常量等级(LVL_), 参数类型(CT_), 文本内容, 数值内容 */ _WT(常量_ZERO), _WT(ZERO), NULL, LVL_SIMPLE, CT_NUM, NULL, 0 ,/数值常量 _WT(常量_TEST), _WT(TEST), NULL, LVL_HIGH, CT_TEXT, TEST, NULL /文本常量;#endif常量等级有: LVL_SIMPLE 1 / 初级 LVL_SECONDARY 2 / 中级 LVL_HIGH 3 / 高级参数类型有: CT_NUM 1 / sample: 3.1415926 CT_BOOL 2 / sample: 1 CT_TEXT 3 / sample: abc文本内容是CT_TEXT用,数值内容是CT_NUM和CT_BOOL用。3) 定义数据类型 DataTypes#ifndef _E_STATIC_LIB用作提供支持库自定义数据类型,包含窗口单元INT DatatypeCommandIndexs = 2;static LIB_DATA_TYPE_INFO DataTypes = /* 中文名称, 英文名称, 数据描述, 索引数量, 命令索引, 对象状态, 图标索引, 事件数量, 事件指针, 属性数量, 属性指针, 界面指针, 元素数量, 元素指针 */ _WT(数据类型命令), _WT(DatatypeCommand), _WT(测试数据类型命令。), sizeof(DatatypeCommandIndexs)/sizeof(DatatypeCommandIndexs0), DatatypeCommandIndexs, NULL, 0, 0, NULL, 0, NULL, NULL, 0, NULL ;#endif关于LIB_DATA_TYPE_INFO的解释 以及 窗口型数据的定义 都可参见开发文档 m_pDataType成员说明和数据类型说明。4) 定义函数 ExecuteCommand,Commands函数书写规范是EXTERN_C void mylib_函数名(PMDATA_INF pRetData, INT iArgCount, PMDATA_INF pArgInf).;函数的实现都需要定义在宏的外面,但ExecuteCommand,Commands则需要定义在宏的里面。pRetData 输出数据指针。当对应CMD_INFO中m_dtRetType为_SDT_NULL(即定义无返回值)时,pRetData无效;iArgCount 函数参数个数pArgInf 函数参数指针#ifndef _E_STATIC_LIBPFN_EXECUTE_CMD ExecuteCommand = mylib_函数名 / 所有需要库中调用的函数都列在这里,用逗号隔开;static const char* const CommandNames = mylib_函数名 / 所有需要库中调用的函数名都写在这里,用逗号隔开;ARG_INFO CommandArgs =/* 参数名称, 参数描述, 图像索引, 图像数量, 参数类型(参见SDT_), 默认数值, 参数类别(参见AS_) */ _WT(参数1), _WT(本命令的参数1), 0, 0, SDT_INT, NULL, NULL /函数参数数组定义写在这里,每个为一个参数的表述,用逗号隔开;static CMD_INFO Commands= /* 中文名称, 英文名称, 对象描述, 所属类别(-1是数据类型的方法), 命令状态(CT_), 返回类型(SDT_), 此值保留, 对象等级(LVL_), 图像索引, 图像数量, 参数个数, 参数信息 */ _WT(函数名), _WT(英文函数名), _WT(函数功能描述), 1, NULL, SDT_BOOL, 0, LVL_SIMPLE, 0, 0, 1, CommandArgs ,/基本命令;#endif注: a. 函数名前的前缀 mylib_ 是以后静态库中使用的。要求必须是动态库项目名称mylib的全小写 mylib_。b. 只需对库中需要调出的函数如此处理,其他函数不需要这样书写。c. 如果程序内部需要调用这个函数,只需使用函数名即可,无须前缀。d. 参数类型如果是 AS_RECEIVE_VAR或AS_RECEIVE_VAR_ARRAY或AS_RECEIVE_VAR_OR_ARRAY 则是定义指针变量的。关于数据类型的定义: #define _SDT_NULL 0 / 空白数据类型 #define _SDT_ALL MAKELONG (MAKEWORD (0, 0), 0x8000) / 通用型 /* 仅用于支持库命令定义其参数或返回值的数据类型,当用于定义库命令参数时, _SDT_ALL可以匹配所有数据类型(数组类型必须符合要求)。*/ #define SDT_BYTE MAKELONG (MAKEWORD (1, 1), 0x8000) / 字节 #define SDT_SHORT MAKELONG (MAKEWORD (1, 2), 0x8000) / 短整数 #define SDT_INT MAKELONG (MAKEWORD (1, 3), 0x8000) / 整数 #define SDT_INT64 MAKELONG (MAKEWORD (1, 4), 0x8000) / 长整数 #define SDT_FLOAT MAKELONG (MAKEWORD (1, 5), 0x8000) / 小数 #define SDT_DOUBLE MAKELONG (MAKEWORD (1, 6), 0x8000) / 双精度小数 #define SDT_BOOL MAKELONG (MAKEWORD (2, 0), 0x8000) / 逻辑 #define SDT_DATE_TIME MAKELONG (MAKEWORD (3, 0), 0x8000) / 日期时间 #define SDT_TEXT MAKELONG (MAKEWORD (4, 0), 0x8000) / 文本 #define SDT_BIN MAKELONG (MAKEWORD (5, 0), 0x8000) / 字节集 #define SDT_SUB_PTR MAKELONG (MAKEWORD (6, 0), 0x8000) / 记录用户易语言子程序的代码地址这些数据类型都已经定义在sdk中,在函数中定义参数时调用。动态库制作完成后,把.dll改成.fne 拷贝到易语言的lib文件目录下即可使用。II. 静态库的制作如果你已经按照上面的方法书写代码并制作好了动态库,接着就可以方便的制作静态库了。方法有两种第一种是生成一个静态库项目编译第二种是在原来的动态库项目上修改成静态库项目。方法一)生成静态库项目具体步骤如下:1. 在解决方案上鼠标右键 - 添加 -新建项目 名称输入 mylib_static。程序向导里设置 程序类型 为静态库。去掉预编译头的钩。点击完成。2. 选择动态库列表中的文件,ctrl+C 复制再 新的mylib_static 中ctrl+V拷贝过来。3. 配置mylib_static 项目属性, 选择release配置。修改配置如下:+ 常规 - 字符集 设置为多字节字符集 + 常规 - 全程序优化 设成 无全程序优化 (这里很重要否则会影响 resym.exe 的工作)+ C+选项卡 - 附加包含目录 填入D:E51sdkcppELib+ C+ - 预处理器 - 预处理定义 添加宏 _E_STATIC_LIB+ 生成事件 - 生成后事件 - 命令行 填入 D:E51sdktoolsresym.exe all infile=$(TargetPath) outfile=$(TargetPath)resym.exe 是用来修改lib库连接符号的,以解决连接时符号冲突的问题。程序位置设成你自己sdk所在位置。设置后选择release编译即可。方法二)生成静态库项目具体步骤如下:打开项目管理,点击配置管理器,mylib的配合处下拉菜单选择 新建, 添入名称 release_static, 从此处复制设置选择release创建release_static后开始修改配置如下:+ 常规 - 配置类型 设置为 静态库(.lib)+ 常规 - 全程序优化 设成 无全程序优化+ C+ - 预处理器 - 预处理定义 删除宏 _USRDLL 添加宏 _E_STATIC_LIB+ C+ - 预编译头 - 选择不使用预编译头+ 管理员 - 常规 - 输出文件 改为 $(OutDir)$(ProjectName)_static.lib+ 生成事件 - 生成后事件 - 命令行 填入你 D:E51sdktoolsresym.exe all infile=$(TargetPath) outfile=$(TargetPath)设置修改完成后,选择release_static项目编译静态库运行,需要动态库的fne和静态库的lib. fne放在易语言的lib目录下,lib放在static_lib目录下。这样就可以静态编译了。编译出来的结果将可以脱离任何非系统支持库独立运行。/一个支持库的例子:我们希望库里面有一个函数,没有自定义类型和常量。函数中文名称是 两数相加,英文名称是myadd, 希望调用格式是。小数型 两数相加 (小数型 参数1,小数型 参数2)该函数在库中所属函数分类是基本运算代码如下: + mylib.cpp文件内容#include stdafx.h#include mylib.h#include #include #include #include / 模块内容/定义函数EXTERN_C void mylib_myadd(PMDATA_INF pRetData, INT iArgCount, PMDATA_INF pArgInf)pRetData-m_float = pArgInf0.m_float + pArgInf1.m_float;/#ifndef _E_STATIC_LIBPFN_EXECUTE_CMD ExecuteCommand = mylib_myadd / 所有需要库中调用的函数都列在这里,用逗号隔开;static const char* const CommandNames = mylib_myadd / 所有需要库中调用的函数名都写在这里,用逗号隔开;ARG_INFO CommandArgs =/* 参数名称, 参数描述, 图像索引, 图像数量, 参数类型(参见SDT_), 默认数值, 参数类别(参见AS_) */ _WT(参数1), _WT(加数1,小数型), 0, 0, SDT_FLOAT, NULL, NULL , /函数参数数组定义写在这里,每个为一个参数的表述,用逗号隔开 _WT(参数2), _WT(加数2,小数型), 0, 0, SDT_FLOAT, NULL, NULL /函数参数数组定义写在这里,每个为一个参数的表述,用逗号隔开;static CMD_INFO Commands= /* 中文名称, 英文名称, 对象描述, 所属类别(-1是数据类型的方法), 命令状态(CT_), 返回类型(SDT_), 此值保留, 对象等级(LVL_), 图像索引, 图像数量, 参数个数, 参数信息 */ _WT(两数相加), _WT(myadd), _WT(两个小数相加求和,返回小数), 1, NULL, SDT_FLOAT, 0, LVL_SIMPLE, 0, 0, 2, CommandArgs ,/基本命令;#endif/EXTERN_C INT WINAPI mylib_ProcessNotifyLib(INT nMsg, DWORD dwParam1, DWORD dwParam2)#ifndef _E_STATIC_LIB if(nMsg = NL_GET_CMD_FUNC_NAMES) return (INT)CommandNames; else if(nMsg = NL_GET_NOTIFY_LIB_FUNC_NAME) return (INT)mylib_ProcessNotifyLib; else if(nMsg = NL_GET_DEPENDENT_LIBS) return (INT)NULL;#endifreturn ProcessNotifyLib(nMsg, dwParam1, dwParam2);#ifndef _E_STATIC_LIBstatic LIB_INFO LibInfo =/* 库格式号, GUID串号, 主版本号, 次版本号, 构建版本号, 系统主版本号, 系统次版本号, 核心库主版本号, 核心库次版本号, 支持库名, 支持库语言, 支持库描述, 支持库状态, 作者姓名, 邮政编码, 通信地址, 电话号码, 传真号码, 电子邮箱, 主页地址, 其它信息, 类型数量, 类型指针, 类别数量, 命令类别, 命令总数, 命令指针, 命令入口, 附加功能, 功能描述, 消息指针, 超级模板, 模板描述, 常量数量, 常量指针, 外部文件 */LIB_FORMAT_VER, _T(LIB_GUID_STR), LIB_MajorVersion, LIB_MinorVersion, LIB_BuildNumber, LIB_SysMajorVer, LIB_SysMinorVer, LIB_KrnlLibMajorVer, LIB_KrnlLibMinorVer, _T(LIB_NAME_STR), _GBK_LANG_VER, _WT(LIB_DESCRIPTION_STR), _LIB_OS(_OS_WIN), _WT(LIB_Author), _WT(LIB_ZipCode), _WT(LIB_Address), _WT(LIB_Phone), _WT(LIB_Fax), _WT(LIB_Email), _WT(LIB_HomePage), _WT(LIB_Other), 0, NULL, L

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论