当前位置:编程学习 > VB >>

在VB 中调用动态连接库

答案:
在VB 中调用动态连接库
---- 作 为 一 种 简 单 易 用 的Windows 开 发 环 境,Visual Basic 从 一 推 出 就 受 到 了 广 大 编 程 人 员 的 欢 迎。 它 使 程 序 员 不 必 再 直 接 面 对 纷 繁 复 杂 的Windows 消 息, 而 可 以 将 精 力 主 要 集 中 在 程 序 功 能 的 实 现 上, 大 大 提 高 了 编 程 效 率。 但 凡 事 有 利 必 有 弊。VB 中 高 度 的 封 装 和 模 块 化 减 轻 了 编 程 者 的 负 担, 同 时 也 使 开 发 人 员 失 去 了 许 多 访 问 低 层API 函 数 和 直 接 与Windows 交 互 的 机 会。 因 此, 相 比 而 言,VB 应 用 程 序 的 执 行 效 率 和 功 能 比C/C++ 或Delphi 生 成 的 程 序 要 差。 为 了 解 决 这 个 问 题, 在 一 个 大 型 的VB 开 发 应 用 中, 直 接 调 用Windows API 函 数 几 乎 是 不 可 避 免 的; 同 时, 还 有 可 能 需 要 程 序 员 自 己 用C/C++ 等 开 发 一 些 动 态 连 接 库, 用 于 在VB 中 调 用。 本 文 主 要 讨 论 在32 位 开 发 环 境Visual Basic 5.0 中 直 接 调 用Windows 95 API 函 数 或 用 户 生 成 的32 位 动 态 连 接 库 的 方 法 与 规 则。

---- Windows 动 态 连 接 库 是 包 含 数 据 和 函 数 的 模 块, 可 以 被 其 它 可 执 行 文 件(EXE、DLL、OCX 等) 调 用。 动 态 连 接 库 包 含 两 种 函 数: 输 出(exported) 函 数 和 内 部(internal) 函 数。 输 出 函 数 可 以 被 其 它 模 块 调 用, 而 内 部 函 数 则 只 能 在 动 态 连 接 库 内 部 使 用。 尽 管 动 态 连 接 库 也 能 输 出 数 据, 但 实 际 上 它 的 数 据 通 常 是 只 在 内 部 使 用 的。 使 用 动 态 连 接 库 的 优 点 是 显 而 易 见 的。 将 应 用 程 序 的 一 部 分 功 能 提 取 出 来 做 成 动 态 连 接 库, 不 但 减 小 了 主 应 用 程 序 的 大 小, 提 高 了 程 序 运 行 效 率, 还 使 它 更 加 易 于 升 级。 多 个 应 用 程 序 共 享 一 个 动 态 连 接 库 还 能 有 效 地 节 省 系 统 资 源。 正 因 为 如 此, 在Windows 系 统 中, 动 态 连 接 库 得 到 了 大 量 的 使 用。

---- 一 般 来 说, 动 态 连 接 库 都 是 以DLL 为 扩 展 名 的 文 件, 如Kernel32.dll 、commdlg.dll 等。 但 也 有 例 外, 如16 位Windows 的 核 心 部 件 之 一GDI.exe 其 实 也 是 一 个 动 态 库。 编 写 动 态 连 接 库 的 工 具 很 多, 如Visual C++、Borland C++、Delphi 等, 具 体 方 法 可 以 参 见 相 关 文 档。 下 面 只 以Visual C++ 5.0 为 例, 介 绍 一 下 开 发 应 用 于Visual Basic 5.0 的 动 态 连 接 库 时 应 注 意 的 问 题( 本 文 中 所 有 涉 及C/C++ 语 言 或 编 译 环 境 的 地 方, 都 以VC5 为 例; 所 有 涉 及Visual Basic 的 地 方 都 以VB5 为 例)。

---- 作 为 一 种32 位Windows 应 用 程 序 的 开 发 工 具,VB5 生 成 的exe 文 件 自 然 也 都 是32 位 的, 通 常 情 况 下 也 只 能 调 用32 位 的 动 态 连 接 库。 但 是, 并 不 是 所 有 的32 位 动 态 库 都 能 被VB 生 成 的exe 文 件 正 确 地 识 别。 一 般 来 说, 自 己 编 写 用 于VB 应 用 程 序 调 用 的 动 态 连 接 库 时, 应 注 意 以 下 几 个 方 面 的 问 题:

---- 1、 生 成 动 态 库 时 要 使 用__stdcall 调 用 约 定, 而 不 能 使 用 缺 省 的__cdecl 调 用 约 定;__stdcall 约 定 通 常 用 于32 位API 函 数 的 调 用。

---- 2、 在VC5 中 的 定 义 文 件(.def) 中, 必 须 列 出 输 出 函 数 的 函 数 名, 以 强 制VC5 系 统 将 输 出 函 数 的 装 饰 名(decorated name) 改 成 普 通 函 数 名; 所 谓 装 饰 名 是VC 的 编 译 器 在 编 译 过 程 中 生 成 的 输 出 函 数 名, 它 包 含 了 用 户 定 义 的 函 数 名、 函 数 参 数 及 函 数 所 在 的 类 等 多 方 面 的 信 息。 由 于 在VC5 中 定 义 文 件 不 是 必 需 的, 因 此 工 程 不 包 含 定 义 文 件 时VC5 就 按 自 己 的 约 定 将 用 户 定 义 的 输 出 函 数 名 修 改 成 装 饰 名 后 放 到 输 出 函 数 列 表 中, 这 样 的 输 出 函 数 在VB 生 成 的 应 用 程 序 中 是 不 能 正 确 调 用 的( 除 非 声 明 时 使 用Alias 子 句)。 因 此 需 要 增 加 一 个.def 文 件, 其 中 列 出 用 户 需 要 的 函 数 名, 以 强 制VC5 不 按 装 饰 名 进 行 输 出。

---- 3、VC5 中 的 编 译 选 项" 结 构 成 员 对 齐 方 式(structure member alignment)" 应 设 成4 字 节, 其 原 因 将 在 后 文 详 细 介 绍。

---- 4、 由 于 在C 中 整 型 变 量 是4 个 字 节, 而VB 中 的 整 型 变 量 依 然 只 有2 个 字 节, 因 此 在C 中 声 明 的 整 型(int) 变 量 在VB 中 调 用 时 要 声 明 为 长 整 型(long), 而C 中 的 短 整 型(short) 在VB 中 则 要 声 明 成 整 型(integer); 下 表 针 对 最 常 用 的 C 语 言 数 据 类 型 列 出 了 与 之 等 价 的 Visual Basic 类 型( 用 于 32 位 版 本 的 Windows)。

---- C 语 言 数 据 类 型 在Visual Basic 中 声 明 为 调 用 时 使 用 的 表 达 式

---- ATOM ByVal variable As Integer 结 果 为Integer 类 型 的 表 达 式

---- BOOL ByVal variable As Long 结 果 为 Long 类 型 的 表 达 式

---- BYTE ByVal variable As Byte 结 果 为 Byte 类 型 的 表 达 式

---- CHAR ByVal variable As Byte 结 果 为 Byte 类 型 的 表 达 式

---- COLORREF ByVal variable As Long 结 果 为 Long 类 型 的 表 达 式

---- DWORD ByVal variable As Long 结 果 为 Long 类 型 的 表 达 式

---- HWND, HDC, HMENU ByVal variable As Long 结 果 为 Long 类 型 的 表 达 式 等Windows 句 柄

---- INT, UINT ByVal variable As Long 结 果 为 Long 类 型 的 表 达 式

---- LONG ByVal variable As Long 结 果 为 Long 类 型 的 表 达 式

---- LPARAM ByVal variable As Long 结 果 为 Long 类 型 的 表 达 式

---- LPDWORD variable As Long 结 果 为 Long 类 型 的 表 达 式

---- LPINT, LPUINT variable As Long 结 果 为 Long 类 型 的 表 达 式

---- LPRECT variable As type 自 定 义 类 型 的 任 意 变 量

---- LPSTR, LPCSTR ByVal variable As String 结 果 为 String 类 型 的 表 达 式

---- LPVOID variable As Any 任 何 变 量( 在 传 递 字 符 串 的 时 候 使 用ByVal)

---- LPWORD variable As Integer 结 果 为Integer 类 型 的 表 达 式

---- LRESULT ByVal variable As Long 结 果 为 Long 类 型 的 表 达 式

---- NULL As Any 或 ByVal Nothing 或

---- ByVal variable As Long ByVal 0& 或 VBNullString

---- SHORT ByVal variable As Integer 结 果 为Integer 类 型 的 表 达 式

---- VOID Sub procedure 不 可 用

---- WORD ByVal variable As Integer 结 果 为Integer 类 型 的 表 达 式

---- WPARAM ByVal variable As Long 结 果 为 Long 类 型 的 表 达 式

---- 5、VB 中 进 行32 位 动 态 库 的 声 明 时, 函 数 名 是 大 小 写 敏 感 的。 在 获 得 了 需 要 的 动 态 连 接 库 之 后, 就 可 以 在VB 中 进 行 调 用 了。 但 是, 由 于VB 不 能 验 证 应 用 程 序 传 递 到 动 态 连 接 库 中 的 参 数 值 是 否 正 确, 因 此VB 程 序 中 大 量 的API 调 用 可 能 会 降 低 整 个 应 用 程 序 的 稳 定 性, 也 会 增 加 以 后 维 护 的 难 度。 所 以, 决 定 在VB 程 序 中 直 接 调 用API 函 数 时 要 慎 重, 但 适 当 的 使 用API 调 用 确 实 能 够 有 效 地 提 高VB 程 序 的 性 能。 这 之 间 的 平 衡 需 要 编 程 人 员 根 据 实 际 情 况 来 掌 握。 下 面 就 具 体 介 绍 一 下 在VB 中 调 用API 函 数 时 需 要 做 的 工 作。

---- 要 声 明 一 个DLL 过 程, 首 先 需 要 在 代 码 窗 口 的" 通 用(General)" 部 分 增 加 一 个Declare 语 句。 如 果 该 过 程 返 回 一 个 值, 应 将 其 声 明 为Function:

---- Declare Function publicname Lib "libname" [Alias "alias"] [([[ByVal] variable [As type] [,[ByVal] variable [As type]]...])] As Type

---- 如 果 过 程 没 有 返 回 值, 可 将 其 声 明 为Sub:

---- Declare Sub publicname Lib "libname" [Alias "alias"] [([[ByVal] variable [As type] [,[ByVal] variable [As type]]...])]

---- 缺 省 情 况 下, 在 标 准 模 块 中 声 明 的DLL 过 程, 可 以 在 应 用 程 序 的 任 何 地 方 调 用 它。 在 其 它 类 型 的 模 块 中 定 义 的DLL 过 程 则 是 模 块 私 有 的, 必 须 在 它 们 前 面 声 明Private 关 键 字, 以 示 区 分。 下 面 分 别 介 绍 声 明 语 句 的 各 个 组 成 部 分。

---- 1、 指 定 动 态 库:

---- Declare 语 句 中 的 Lib 子 句 用 来 告 诉 Visual Basic 如 何 找 到 包 含 过 程 的 .dll 文 件。 如 果 引 用 的 过 程 属 于 Windows 核 心 库(User32、Kernel32 或 GDI32), 则 可 以 不 包 含 文 件 扩 展 名, 如:

---- Declare Function GetTickCount Lib "kernel32" Alias &qu

上一个:VB中用API函数实现文件夹列表
下一个:谈谈Windows API 在VB 中的应用

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,