【VB技巧】VB静态调用与动态调用dll详解

2023-11-06

摘 自: http://lcx.cc/?i=489

 

【【请注意】】:在以下语法格式中,请注意 [函数名] 的【大小写】!!!

静态与动态比较:

    静态调用简单,动态调用麻烦;静态调用占用资源多,动态调用占用资源少;正所谓鱼和熊掌不可兼得。


静态调用定义:

    就是常用的申明API,一个DLL库里有很多的函数可供调用,把要用的申明即可。
    比如:Public/Private Declare Function [函数名] Lib "DLL文件名" [Alias "别名"] (参数变量表) [As 返回值的数据类型]
    示例:Private Declare Function Test Lib "dll.dll" (x As String) As String
    当程序结束的时候系统回自动释放DLL调用。


动态调用定义:

    使用LoadLibery(DLL名),系统会检查DLL是否调入内存。如果调入了,可直接调用DLL里的所有函数,没有就会把DLL加入目标进程的进程空间。通过函数GetProcAddress确定函数入口地址,然后调用,后一种方法VB里不常用的。


静态调用详解:

    制作好DLL之后,首先用Declare声明语句在窗体级或模块级或全局模块的代码声明段进行声明,将动态链接库中的函数声明到VB中,供VB程序调用。

    语法格式1:
        Public/Private Declare Sub [函数名] Lib "DLL文件名" [Alias "别名"] (参数变量表)

    语法格式2:
        Public/Private Declare Function [函数名] Lib "DLL文件名" [Alias "别名"] (参数变量表) [As 返回值的数据类型]

    在声明中首先用Declare关键字表示声明DLL中的函数。在C语言中有的函数类型为VOID,它表示不具有返回值,则必须用关键字Sub将其声明成过程。有的函数具有返回值,则必须用关键字Function将其声明成函数,并且在声明语句的最后要用AS关键字指明函数返回值的类型。

    例如add.DLL在VB中就可以声明为:
        Declare Function ADD Lib "c:\add.dll" (ByVal X AS Integer, ByVal Y AS Integer, ByVal filein as string) AS Integer

    通过此声明语句将函数ADD声明到VB中,便可直接调用。


动态调用详解:

    首先调用API LoadLibaray 装载dll,然后调用API GetProcAddress 得到dll的对应方法的地址。因为vb不像其他的有函数指针,在vb中声明函数原形,怎样把得到的函数地址赋给这个原形有些麻烦。

解决办法1:

Option Explicit 
 
'我们要调用没有声明的API(dll)的功能! 
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long '释放LoadLibrary载入的动态链接库,非零表示成功,零表示失败。 
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long '载入指定动态链接库,成功则返回库模块的句柄,零表示失败。 
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long '检索指定的动态链接库(DLL)中的输出库函数地址(超找函数入口地址),成功则返回值是DLL中的输出函数地址,失败返回值是NULL。 
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Any, ByVal wParam As Any, ByVal lParam As Any) As Long '将消息信息传送给指定的窗口过程。 
 
Private Sub Form_Load() 
    Dim LibHand As Long '载入的dll句柄 
    LibHand = LoadLibrary("user32")     '将user32载入到内存。 
    CallWindowProc GetProcAddress(LibHand, "SetWindowTextA"), Me.hWnd, CStr(Now), ByVal 0&, ByVal 0& '调用SetWindowTextA函数功能 
    FreeLibrary LibHand '释放映射库的地址 
End Sub



解决办法2:
 
下面是动态调用MessageBoxA的源代码,上面的步骤被封装到RunDll32函数中,可放到模块(CallAPIbyName.bas)中: 
    Dim s1() As Byte, s2()   As Byte 
    Const hWnd = 0 
    Dim ret  As Long 
    s1 = StrConv("Hello~World", vbFromUnicode) 
    s2 = StrConv("VBNote", vbFromUnicode) 
    ret = RunDll32("user32", "MessageBoxA", hWnd, VarPtr(s1(0)), VarPtr(s2(0)), 0&) 
End Sub 
 
Public Function RunDll32(LibFileName As String, ProcName As String, ParamArray Params()) As Long 
    Dim hProc As Long 
    Dim hModule As Long 
    ReDim m_OpCode(400 + 6 * UBound(Params))    '保留用来写m_OpCode 
    hModule = LoadLibrary(ByVal LibFileName)    '读取API库 
    If hModule = 0 Then 
MsgBox "Library读取失败!" 
Exit Function 
    End If 
    hProc = GetProcAddress(hModule, ByVal ProcName)     '取得函数地址 
    If hProc = 0 Then 
MsgBox "函数读取失败!", vbCritical 
FreeLibrary hModule 
Exit Function 
    End If 
    RunDll32 = CallWindowProc(GetCodeStart(hProc, Params), 0, 1, 2, 3)  '执行Assembly   Code部分 
    FreeLibrary hModule '释放空间 
End Function

解决办法3:

在VB中嵌入汇编实现。loadlibary取得DLL,GetProcAddress取得函数地址,用VB嵌入汇编的写法压所需参数,CallWindowProc调用GetProcAddress返回的地址。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【VB技巧】VB静态调用与动态调用dll详解 的相关文章

  • Qt5实现与单片机ATS89S51通信

    Qt实现与单片机直接的通信上位机 单片机代码 测试环境 项目目标 实现效果 关键通信类 QSerialport 总结 这是我大二下学期的单片机课设做的一个小项目 实现上位机与下位机之间的通信 测试环境 开发环境 Qt5 96 Mingw32
  • 每天都在谈SOA和微服务,但你真的理解什么是服务吗?

    近几年来 我一直从事着和面向服务相关的底层软件研发工作 逐渐的形成了一些自己的看法 其中我觉得比较重要的看法就是服务需要一个更准确细致的定义 简单来说 服务的本质就是行为 业务活动 的抽象 为了更好的阐述新服务的概念 并方便与传统的SOA中
  • 【C/C++】报错问题积累

    1 出现Deprecated declaration XXX give arg types c文件中 有没有参数的函数时 声明需要加void即 main c void fun main h void fun void
  • C++中的namespace

    namespace中文意思是命名空间或者叫名字空间 传统的C 只有一个全局的namespace 但是由于现在的程序的规模越来越大 程序的分工越来越细 全局作用域变得越来越拥挤 每个人都可能使用相同的名字来实现不同的库 于是程序员在合并程序的
  • std::nth_element bug引起的crash问题

    1 源码 auto less compare const MirroringGroup mg1 const MirroringGroup mg2 gt bool return mg1 usage lt mg2 usage std nth e
  • JNA模拟复杂的C类型——Java映射char*、int*、float*、double*

    文章目录 引言 Java Native Type Conversions Java和C基本类型指针对应关系 Pointer的具体用法 引言 最近项目在用Java调用C写的一些三方库 没办法直接调 用Java封装一下C的接口 这就少不了要用到
  • C/C++中浮点数格式学习——以IEEE75432位单精度为例

    这是浮点数的通常表示形式 在IEEE754中 单精度浮点数有如下形式 32位单精度 单精度二进制小数 使用32个比特存储 1 8 23位长 S Exp Fraction 31 30至23偏正值 实际的指数大小 127 22至0位编号 从右边
  • 无法打开源文件<sys/time.h>,但是用time.h编译就会出错,缺少gettimeofday()

    因为sys time h是uinx系统下的库文件 而现在使用的平台是在windows 由于未指明程序运行的系统 导致找不到对应的头文件 需要重新实现gettimeofday 函数 define WIN32 include
  • BP学习算法-构建三层神经网络

    引 人工神经网络 Artificial Neural Networks 简写为ANNs 也简称为神经网络 NNs 或称作连接模型 Connection Model 是一种模仿动物神经网络行为特征 进行分布式并行信息处理的算法数学模型 这种网
  • vector,list,deque区别

    http blog csdn net renkaihao article details 6803866 vector和built in数组类似 它拥有一段连续的内存空间 并且起始地址不变 因此它能非常好的支持随即存取 即 操作符 但由于它
  • ATL字符串转换宏

    有比MultiByteToWideChar和WideCharToMultiByte更简单的字符串转换宏 你相信吗 头文件 d program files microsoft visual studio 8 vc atlmfc include
  • LeetCode题目笔记——17.19消失的两个数字

    文章目录 题目描述 题目难度 困难 方法一 暴力 代码 代码优化 方法二 数学方法 代码 总结 题目描述 题目直达 题目难度 困难 方法一 暴力 虽然题目说你能在 O N 时间内只用 O 1 的空间找到它们吗 但是也没有限制我们不能用暴力
  • R----dplyr包介绍学习

    dplyr包 plyr包的替代者 专门面对数据框 将ddplyr转变为更易用的接口 gt 来自dplyr包的管道函数 其作用是将前一步的结果直接传参给下一步的函数 从而省略了中间的赋值步骤 可以大量减少内存中的对象 节省内存 可惜的是应用范
  • C++:指向类的成员的指针

    引 想必接触过C的朋友们对C语言中指针的概念已经有了深入的了解 如果初步进行了解的朋友可以看一下 C语言基础学习笔记 指针展开来讲的基本知识点包括 指针的概念 指针的定义和初始化及简单使用 指针函数和函数指针 有关指针函数和函数指针的内容上
  • 检查内存泄露

    自己编写的视频处理程序出现了一个问题 每帧的运行时间随着运行时间在不断增长 很大可能是出现了内存泄露 于是学习了一些查看内存泄露的方法 做了两种尝试 一是VS自带的DEBUG下的检测 view pl html view plain copy
  • 一个简单的参数帮助框架,c实现

    文章目录 具体实现如下 include
  • C 语言运算符详解

    C 语言中的运算符 运算符用于对变量和值进行操作 在下面的示例中 我们使用 运算符将两个值相加 int myNum 100 50 虽然 运算符通常用于将两个值相加 就像上面的示例一样 它还可以用于将变量和值相加 或者将变量和另一个变量相加
  • C 语言运算符详解

    C 语言中的运算符 运算符用于对变量和值进行操作 在下面的示例中 我们使用 运算符将两个值相加 int myNum 100 50 虽然 运算符通常用于将两个值相加 就像上面的示例一样 它还可以用于将变量和值相加 或者将变量和另一个变量相加
  • C++ 字符串比较------strcmp函数和strncmp函数

    strcmp 函数原型 int strcmp const char str1 const char str2 功能 strcmp函数会按照字典顺序逐个比较两个字符串的字符 直到遇到不同的字符或者遇到字符串结束符 0 返回值 该函数返回值如下
  • 在 OS X 上的 virtualenv 中安装 scrapy 加密时发生错误 [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我正在安装 scrapypip in virtualenv on OS X 10 11 当它安装密码学时 它说 buil

随机推荐

  • FreeBSD ssh配置

    freebsd ssh配置 2011 08 22 15 35 32 分类 系统运维 freebsd 默认是不允许ssh登录的 说以说要设置一下 我的版本是8 2的从网上的一个博客中获得了信息然后成功了 http likuan4168 blo
  • K8s pod 应用

    个人学习笔记 如有问题欢迎交流 文章编排和格式等问题见谅 1 编写 pod yaml 文件 pod 是 kubernetes 中最小的编排单位 一个 pod 里包含一个或多个容器 apiVersion v1 指定api版本 kind Pod
  • 数据可视化——简单图形绘制(饼图,柱状图,直方图,散点图,箱线图,折线图)

    各种图形的label参数都与plt legend函数配合使用 import pandas as pd import numpy as np import matplotlib pyplot as plt 更改文件存放提取路径 import
  • pjsip视频通信开发(底层实现)之用户注册

    一 PJSIP简介 对于pjsip的介绍可以看http www cnblogs com my life articles 2175462 html 文章 里面详细介绍了它的组成框架以及各部份的组成介绍 我把官网中提供的一个pjsip的整体框
  • angularJs 一些API

    angular bind 返回一个调用self的函数fn self代表fn里的this 可以给fn提供参数args 这个功能也被称为局部操作 以区别功能 格式 angular bind self fn args self object 对象
  • Swiper参数说明(swiper参数配置)

    1 自由模式与滑块容器 Free Mode and Scroll Container Parameter 参数 Type 类型 Default Value 默认值 Example 例子 Description 说明 speed number
  • 计算机教师招聘笔试总结

    大专数字媒体专业教师中级岗 笔试内容 数字媒体技术 艺术史 计算机图形学 虚拟现实 数字媒体艺术 数据库 教育基础 笔试成绩 第一且只有我一人进面 准备时间 一周 准备过程 这所学校3月份就发了招聘简章 但因为我白天要上课 晚上要打游戏 所
  • Eclipse中断点调试的基本使用

    Eclipse中断点调试的基本使用 A Debug的作用 调试程序 查看程序执行流程 B 如何查看程序执行流程 什么是断点 就是一个标记 从哪里开始 如何设置断点 你想看哪里的程序 你就在那个有效程序的左边双击即可 在哪里设置断点 哪里不会
  • 2021年第十二届蓝桥杯javaA组国赛

    文章目录 试题 A 纯质数 试题 B 完全日期 试题 C 最小权值 试题 D 覆盖 试题 E 123 试题 F 二进制问题 试题 G 冰山 试题 H 和与乘积 试题 I 异或三角 试题 J 积木 以下均为个人想法和解题思路 如有错误或不足
  • openGL之API学习(五十二)透视分割 透视除法的执行位置

    根据文章https blog csdn net hankern article details 89220736 的分析 透视分割 又叫透视除法 执行的位置在栅格化阶段
  • Integer类型和int类型比较是否相等 == equals - Java

    非常经典的一个面试题 先说清楚一个 再来说另一个 用来判断两个变量之间的的值是否相等 变量就可以分为 基本数据类型变量 引用类型 1 基本数据类型的变量直接比较值 2 引用类型比较对应的引用指向的内存的首地址 equals只有引用数据类型有
  • docker的运行原理

    Docker 是一个开源的容器化技术 它能够让开发者将应用及其依赖打包到一个轻量级的 可移植的容器中 这个容器可以在几乎任何机器上一致地运行 要了解 Docker 的运行原理 我们首先要理解以下几个核心概念 容器 Container 容器是
  • android自定义控件onclick,android – 如何在ImageButton中设置onClick事件?

    我在 android中创建了一个图像按钮 但是当我点击该按钮时没有发生任何事情 我已经设置了所有属性 但仍然没有发生任何事情 所以 在我错的地方 你能帮助我吗 xml文件 android id id widget39 android lay
  • 产品数据管理系统框架与信息安全

    2 1引言 产品数据管理 Product Data Management PDM 以产品为中心 通过计算机网络和数据库技术 把企业生产过程中所有与产品相关的信息和过程集成起来 统一管理 使产品数据在其生命周期内保持一致 最新和安全 为工程技
  • Vue中如何进行数据缓存

    Vue中如何进行数据缓存 Vue是一款流行的前端框架 它提供了许多方便的功能来处理数据 其中一个非常有用的功能是数据缓存 数据缓存可以提高应用程序的性能 减少网络请求 提高用户体验 在本文中 我们将介绍Vue中如何进行数据缓存 并提供一些示
  • 用html实现一个静态登陆页面-可根据需求更改样式

    一 创建html文件 vscode下载相关插件 我们先选择一个文件夹创建login html 之前的文件命无所谓 之后就必须为html或者htm 在编辑改文件输入 且出现提示后按回车或按tab快捷生成基础代码 然后我们下载一个可以方便我们开
  • 解决数据库连接池连接mysql时,每隔8小时mysql自动断开连接的问题

    解决数据库连接池连接mysql时 每隔8小时mysql自动断开所有连接的问题 最近有个问题非常讨厌 我们的工程中使用自己的连接池连接mysql数据库 可mysql数据库每隔8小时就会自动断开所有链接 连接池就失效 需要重新启动tomcat才
  • 组合类、派生类 拷贝构造函数

    在派生类中如何写拷贝构造函数 一种形式 派生类拷贝构造函数名 对象p的引用 基类构造函数名 参数列表 如 student student student p stud p num p name p sex 注意 参数形式 是对象的引用 我们
  • java基础题实现猴子吃桃的问题

    一只猴子一天摘了许多桃子 第一天吃了一半 然后忍不住又吃了一个 第二天又吃了一半 再加上一个 后面每天都是这样吃 到第10天的时候 小猴子发现只有一个桃子了 问小猴子第一天共摘了多少个桃子 问题分析 第十天时只剩下一个桃子 又知道猴子每次吃
  • 【VB技巧】VB静态调用与动态调用dll详解

    摘 自 http lcx cc i 489 请注意 在以下语法格式中 请注意 函数名 的 大小写 静态与动态比较 静态调用简单 动态调用麻烦 静态调用占用资源多 动态调用占用资源少 正所谓鱼和熊掌不可兼得 静态调用定义 就是常用的申明API