【小工具】VB6.0制作“标准DLL”----彻底摆脱ActiveX DLL的影子

舉杯邀明月 2013-10-09 12:01:42
加精
  关于用VB6.0制作“标准DLL”这件事,网上早已出现过不少的争论了。我在这儿也不想对以前的事发表过多的评论。
只是说一下最关键的区别:以前的各种制作方法,归根结底做出来的还是ActiveX DLL,只是比VB6直接编译出来的多了导
出函数罢了;而使用我的这个小程序弄出来的DLL,就不再是 ActiveX DLL !
  废话不多说,上图为证。
  先上张用以前流传的方法做出的DLL的“效果图”。这是我用http://bbs.csdn.net/topics/390589259所提到的方法做
了个简单的示例。老马他们那儿曾经发布了个“函数添加大师”,我以前下载来看了下他的说明,但没安装使用,从他所
说的来看,也是“带导出函数的ActiveX DLL”,只是使用比较方便罢了。

  下面就上张用我的这个工具做出的DLL的“效果图”了。是把我上次发布的MD5模块稍作修改做了个DLL样例。这是实
在的效果图,并不是把那几个函数 PS掉了的!

软件界面样图:

别的我不想再写了,下面把我写的软件“说明”文件的内容贴出来。
欢迎大家发表见解。
一会儿我把这些相关东西打包上传到资源,如果有兴趣的就下载来看看。


⒈ 概述
  VB6.0本身只支持制作ActiveX DLL文件。对于用VB6.0制作“标准DLL”(当然这
是“狭义”的标准DLL:指带导出函数、直接调用的DLL,不用通过对象来调用),网
上早已出现过不少的争论,但争来争去,似乎都是谁也没说服谁。网上也流传过不少
的“用VB6.0制作标准DLL的方法”,虽然或繁或简,还有的做成了VB6.0的插件,但
是这些方法的实质如出一辙,做出来的DLL文件,也仅仅是“带导出函数的ActiveX
DLL”而已。虽然带有导出函数,可以直接通过"Declare"来使用了,其实它们并没有
彻底摆脱ActiveX DLL的影子。
  不过,用我这个制作工具链接的DLL,就不再是ActiveX DLL了。可以用M$出品的
Dependency Walker工具对制作出来的DLL文件查看对比,就明显看出区别:以前网流
传的方法做出的DLL,如图片“DllTest”中所示,都会有四个如影随形的函数:
DllRegisterServer、DllUnregisterServer、DllGetClassObject、DllCanUnloadNow
而用我的这个工具做出来的DLL文件,这几个函数就彻底消失了!因为根本不需要任
何Class模块来做承载体。效果如图片“MD5Fun”中所示。
  当然,由于开发平台的关系,做出来的DLL代码要能执行,当然也基本是离不开
MSVBVM60.DLL的支持。用VB6做出的东西要摆脱它,可不是一般的功力可及的!!!


⒉ 软件安装
  最初是打算做个安装程序的,不过后来觉得没什么意思。毕竟这也基本上是个没
太大应用价值东西,可能大家也只是“试一下”而已,并且这个“安装”并不复杂,
不想再折腾那么多了。
“手工安装”过程如下:
  ①在VB6安装目录中,把原来的“Link.exe”名字改成Link2。注意:不要用其它
名字,更不能把它删除了!因为最终的链接操作,仍然是调用这个程序来完成的,我
的程序只是做了一些“前期工作”。
  ②把我的“Link.exe”复制到VB6安装目录中。至此,最关键的操作就完成了。
  ③安装“Standard DLL”模板。把 StdDLL.vbp和Dll_Main.bas 这两个文件,复
制到“VB6安装目录\Template\PROJECTS”中就行。如果Template或PROJECTS目录不
存在,可以自选创建(注意路径的层次关系)。
  安装模板后,在新建工程中,就能使用这个模板来创建标准DLL框架了,如图片
“新建工程”中所示。如果你安装的是企业版,它带的模板可能比较多,这个模板可
能排在最后面去了,你需要拖动右边的滚动条,让它显示出来。
  “标准DLL模板”也可以不用安装。如果要用这个工具做“标准DLL”,只要新建
一个“标准EXE工程”,然后:移除窗体模块Form1、新建一个“模块”Module1,再
在Module1中写个Sub Main()过程,最基础的框架就完成了!
比如这样写:
Private Sub Main(): End Sub
甚至,你可以 Private/Public 都不写,就写“Sub Main(): End Sub”就行了!

  剩下的,就是你自己的DLL所用的Function、Sub等要做的事了。


⒊ 软件界面
  你所能看到的,就是一个窗口,如图片“窗口界面”中所示。左边树形列表,是
各个可用的模块,以及其所包含的可用导出函数。右边是列表框,列出你已经选定添
加的导出函数。青色背景的标签,显示内容是:你在树形列表中选定的函数或模块所
在的“源文件”路径。“基址地址”含义没什么可解释的,一般还是不要改它为好。
另外,输入的数值直接按16进制解释,并且 &H或0x 字头不要输入。添加好需要的导
出函数后,点“确定”就可链接好DLL文件。
如何“添加导出函数”,请继续往下看……


⒋ 软件操作
  在你的源代码编写好后,请先保存一次你的工程源码(各模块都必须保存,代码
作了修改再次编译时,可以不用保存),然后在VB6.0的IDE中,菜单操作:
“文件”-→“生成xxxxx.xxx(K)...”[注:这儿显示的是.exe还是.dll,不用管]
然后在弹出的窗口中,选择好输出的磁盘路径及文件名。这步有个非常重要的地方:
在第一次编译时,一定要在输出文件的后面加上“.dll”(大小写都可以)。一定要
注意,如果你不指定.dll后缀,它就是链接成.exe文件了!但你再次对本工程编译链
接时,直接确定就行。
  选择好输出路径、输出文件名,如果指定了.dll,点“确定”后,就会出现本软
件的窗口。要添加导出函数,可以在左边树形列表的节点中,点“模块名”,再点右
边的按钮“添加该模块”,把选定模块中的所有函数添加到导出函数列表;或者以稍
慢的速度“双击”函数节点,把选定的一个函数添加到导出函数列表(点太快不行,
它没响应的。它没有双击事件,并且太快了鼠标消息还会被吃掉)。如果要删除已经
添加的函数,则在右边列表框中,双击相应项目移除一个,或点按钮“清空列表”全
部删除。5个按钮都设有访问键,大家一看界面就知道了,我不必多说。
  如果某函数已经在导出列表中,则左边树形列表的函数节点上,函数名左边的图
标会显示一个绿色的“钩”号,而没有添加的函数,它的图标只是一个白框。当你在
左边树形列表的函数节点上,点中已经添加的函数,则右边列表框中对应项目也会自
动被选定;如果在树形列表中选定的函数未添加,或者选中的是模块节点,则右边列
表框就没有项目被选定。同样,当你在选定右边列表框中的任意一个项目时,左边树
形列表对应的函数节点也自动选定。任何时候,青色标签中都显示着树形列表函数节
点或模块节点对应的源文件路径。
  点“取消”可以放弃链接操作(会询问)。
  点“复位”可以恢复前一次选定的导出函数列表(本工程如果是第一次编译,则
跟“清空列表”的效果一样)。
  如果关闭窗口,则直接放弃链接操作(不询问)。
  当选择后导出函数列表后,点“确定”,随后就进行DLL文件的链接操作。这个
时候,你当前的工程模块信息、导出函数列表信息等,会在临时文件夹中,保存到
"CompInfo.db"文件中(这个文件内容你别改,否则可能失效了),这样,当你对源
码进行了修正,再次编译链接时,可以不用再次进行导出函数的添加操作。
  “提醒选择导出函数列表”选项默认选定,这样每次编译链接,窗口都会弹出。
你也可以在“确定”前去掉它的钩选,这样,如果工程中“可用的导出函数列表”没
有变化,比如你只是对各个Sub/Function的代码做了修改,或加了、减了个类模块什
么的(因为类模块、窗体模块都不支持“导出函数”),控制窗口就不再弹出,按已
经选定的导出函数列表进行链接操作。
  当你在任意标准模块中增加或删除了Sub/Function时,或者改变输出文件路径、
输出文件名时(这时要再次指定.dll后缀!),控制窗口就会重新出现了。如果你把
临时文件夹中的"CompInfo.db"文件删除后再编译,控制窗口也会出现。

...全文
27715 128 打赏 收藏 转发到动态 举报
写回复
用AI写文章
128 条回复
切换为时间正序
请发表友善的回复…
发表回复
loakia4 2016-07-04
  • 打赏
  • 举报
回复
我顶。。。。。。
舉杯邀明月 2016-06-24
  • 打赏
  • 举报
回复
引用 136 楼 qq_35408643 的回复:
前面步骤都对,但找不到生成的DLL文件。
前面都对,但“后面的操作”呢,是不是没按要求做? 保存文件的目录,就是在VB6的“生成工程”对话框指定的目录。 如果DLL文件链接成功,肯定会有一个你指定名称的dll文件在那儿。 如果有什么问题,要把问题现象描述清楚啊! 1. 出现“DLL导出函数管理窗口”? 2. 在导出函数管理窗口中,点“确定”之后,它有没有报告错误消息? 另外,请下载最新版本的 DLL制作工具:  VB6.0_DLL制作工具(Ver2.01)
qq_35408643 2016-06-24
  • 打赏
  • 举报
回复
前面步骤都对,但找不到生成的DLL文件。
baidu_25011791 2016-03-27
  • 打赏
  • 举报
回复
顶一个。
Julang-Yang 2015-12-24
  • 打赏
  • 举报
回复 1
引用 133 楼 Chen8013 的回复:
[quote=引用 131 楼 hk756yang 的回复:] [quote=引用 129 楼 Chen8013 的回复:] [quote=引用 128 楼 hk756yang 的回复:] Win10,64位,vb6,试了很多次,都没有成功。“编译错误:子程序或函数未定义”。在vb编译的exe文件时是这样,在Excel2013 的VBA中也是这样的错误。
编译错误:子程序或函数未定义” 这是你自己的代码错误啊! [/quote] VB的问题找到了,函数中有引用的变量,写错了。经过试验,Win10 64位系统,VB6.0,可以编译并调用VB6生成的带窗体和弹出框的标准DLL。但是office2013 64位和CAD2014 64位确实不能调用VB6.0编译生成的标准DLL,经过搜索,就是因为我用的系统都是64位的文档,而且是在Win10 64位系统,所以没法调用VB6.0生成的32位的DLL。如果是Win7的64位系统,也许可以调用VB6.0生成的32位的DLL。 在Win10 64位系统中,一个简单的getobject语句都无法实现,何况是32位DLL调用呢。[/quote] VB6是32位的,它编译出来的东西,肯定只能用于Win32的环境。 你用64位的 Office、CAD软件,肯定不能调用VB6编译出的dll。 至于你说的“64位系统中,一个简单的getobject语句都无法实现”,这些我倒是不清楚具体情况。 64位的Office,我还没有使用过,以前我用64位Win7的时候,安装的是Office2003。 现在公司里的电脑是32位的Win7专业版,安装的Office 2007。 目前还没使用过07以上的Office版本(我不是什么软件都要用“最新”的那种人) [/quote] Win10系统下调用GetObject的语句已经解决了,问题还是出在我的代码上。由于VB6调用GetObject在Win10系统不起作用,受其误导,我在office宏和VS2013中的GetObject调用代码都不正确,所以也用不了。这问题困扰了我几个月时间。前几天在网上搜索到在VBA7中使用Getopenfilename API时,顺便点开了一个介绍64位的Win32 API的网页,经过仔细查看,终于解决了Win10系统的GetObject的调用,同时在office64位的宏中GetObject调用也成功实现。这说明有时候代码中可能只是一个小错误,但要检查出来却很困难,所以,一定要仔细!多谢Chen8013
舉杯邀明月 2015-12-22
  • 打赏
  • 举报
回复
引用 131 楼 hk756yang 的回复:
[quote=引用 129 楼 Chen8013 的回复:] [quote=引用 128 楼 hk756yang 的回复:] Win10,64位,vb6,试了很多次,都没有成功。“编译错误:子程序或函数未定义”。在vb编译的exe文件时是这样,在Excel2013 的VBA中也是这样的错误。
编译错误:子程序或函数未定义” 这是你自己的代码错误啊! [/quote] VB的问题找到了,函数中有引用的变量,写错了。经过试验,Win10 64位系统,VB6.0,可以编译并调用VB6生成的带窗体和弹出框的标准DLL。但是office2013 64位和CAD2014 64位确实不能调用VB6.0编译生成的标准DLL,经过搜索,就是因为我用的系统都是64位的文档,而且是在Win10 64位系统,所以没法调用VB6.0生成的32位的DLL。如果是Win7的64位系统,也许可以调用VB6.0生成的32位的DLL。 在Win10 64位系统中,一个简单的getobject语句都无法实现,何况是32位DLL调用呢。[/quote] VB6是32位的,它编译出来的东西,肯定只能用于Win32的环境。 你用64位的 Office、CAD软件,肯定不能调用VB6编译出的dll。 至于你说的“64位系统中,一个简单的getobject语句都无法实现”,这些我倒是不清楚具体情况。 64位的Office,我还没有使用过,以前我用64位Win7的时候,安装的是Office2003。 现在公司里的电脑是32位的Win7专业版,安装的Office 2007。 目前还没使用过07以上的Office版本(我不是什么软件都要用“最新”的那种人
Julang-Yang 2015-12-20
  • 打赏
  • 举报
回复
引用 130 楼 Chen8013 的回复:
错误提示的内容、含义已经很明确了。 你自己代码中用到的某个(或者“某些”)函数没有编写、或者调用别的模块的函数但那个函数是“私有”的。
你说的没错,我本来想直接用了你的例子 Private Sub MaxNum(ByVal a As Long, ByVal b As Long) ' 简单示例:传入2个整数,找出较大值。 Dim stcBuf As String * 16 ' 字符串缓冲区 Dim i As Long, p As Long If (b > a) Then a = b p = StrPtr(stcBuf) + 30 ' 缓冲区总共32字节 ' 数值转换成10进制表示的字符串 i = Abs(a) …… 就是这个函数和下一个函数,都有两个参数。但是在编译了DLL之后,调用的时候,声明的时候,函数括号里是空的,漏掉了两个参数,所以编译出错。补上两个参数后,再编译VB exe就没错了。
Julang-Yang 2015-12-20
  • 打赏
  • 举报
回复
引用 129 楼 Chen8013 的回复:
[quote=引用 128 楼 hk756yang 的回复:] Win10,64位,vb6,试了很多次,都没有成功。“编译错误:子程序或函数未定义”。在vb编译的exe文件时是这样,在Excel2013 的VBA中也是这样的错误。
编译错误:子程序或函数未定义” 这是你自己的代码错误啊! [/quote] VB的问题找到了,函数中有引用的变量,写错了。经过试验,Win10 64位系统,VB6.0,可以编译并调用VB6生成的带窗体和弹出框的标准DLL。但是office2013 64位和CAD2014 64位确实不能调用VB6.0编译生成的标准DLL,经过搜索,就是因为我用的系统都是64位的文档,而且是在Win10 64位系统,所以没法调用VB6.0生成的32位的DLL。如果是Win7的64位系统,也许可以调用VB6.0生成的32位的DLL。 在Win10 64位系统中,一个简单的getobject语句都无法实现,何况是32位DLL调用呢。
Julang-Yang 2015-12-18
  • 打赏
  • 举报
回复
Win10,64位,vb6,试了很多次,都没有成功。“编译错误:子程序或函数未定义”。在vb编译的exe文件时是这样,在Excel2013 的VBA中也是这样的错误。
舉杯邀明月 2015-12-18
  • 打赏
  • 举报
回复
错误提示的内容、含义已经很明确了。 你自己代码中用到的某个(或者“某些”)函数没有编写、或者调用别的模块的函数但那个函数是“私有”的。
舉杯邀明月 2015-12-18
  • 打赏
  • 举报
回复
引用 128 楼 hk756yang 的回复:
Win10,64位,vb6,试了很多次,都没有成功。“编译错误:子程序或函数未定义”。在vb编译的exe文件时是这样,在Excel2013 的VBA中也是这样的错误。
编译错误:子程序或函数未定义” 这是你自己的代码错误啊!
Julang-Yang 2015-12-15
  • 打赏
  • 举报
回复
我用的Win10,64位,vb6,以后有机会测试一下,反馈一下。
Julang-Yang 2015-12-15
  • 打赏
  • 举报
回复
看了很多相同的软件工具,也试用过外国朋友的同类软件,用过之后也是出了一些错误,后来放弃了。但是这次看到楼主的工具软件,能连续这么久,更新、讨论,让我花了很长时间从头到尾仔细研读,学习了不少,也发现之前出错的可能地方在哪里。这次好好试试。非常感谢楼主的奉献,谢谢。 支持楼主!不用的人可能觉得这个工具没啥用,用的人会觉得这个工具非常重要。
amai2009 2015-09-21
  • 打赏
  • 举报
回复
支持楼主,我用这个
舉杯邀明月 2015-08-10
  • 打赏
  • 举报
回复
引用 123 楼 godwiser 的回复:
在Win8.1编译没有成功,什么也没生成!
不成功,有没有什么错误信息提示??? 我没有Win8的系统来进行测试。 理论上说,如果你的VB6能在8.1下正常编译你的VB工程(EXE或者ActiveX DLL), 那么用我的工具就能正确编译出DLL。
godwiser 2015-08-09
  • 打赏
  • 举报
回复
在Win8.1编译没有成功,什么也没生成!
舉杯邀明月 2015-07-21
  • 打赏
  • 举报
回复
引用 121 楼 Bobogg 的回复:
[quote=引用 118 楼 Chen8013 的回复:]
问题多半是出在你的代码编写,或者这个dll只能在exe中调用。
这个dll只能用于exe来调用,它就不能用于vba环境。


vb6_ide --> 成功
vb6_exe --> 成功
vba --> 死机

目前看来原因是不能用于 vba
只是原因是什么呢? 想不出ㄟ[/quote]
我今天特意试了一下,在我这儿是没有问题的。
我的运行环境是:Win7/32位专业版 + MS Office2007

你的DLL代码是用的Sub,因此我在代码中加了 MsgBox 语句,以指示运行结果。
经测试,在VB6 IDE下运行、 微软Office 2007的Word、Excel、PowerPoint这三个组件中VBA环境中运行,
都是完全正常的!

DLL代码如下(只是导出函数模块部分):
Option Explicit

Public Sub qq5() ' 死机
Dim w As Long
Dim s As Variant

For w = 1 To 100
s = s + 1
Next
MsgBox s, 64, "DLL 测试1"
End Sub

Public Sub qq6() ' 死机
Dim s As String
Dim w As Long
For w = 1 To 100
s = s & 1
Next
MsgBox s, 64, "DLL 测试2"
End Sub


VBA的调用代码如下:
Private Declare Sub qq5 Lib "E:\Temp\Std_DLL.dll" ()
Private Declare Sub qq6 Lib "E:\Temp\Std_DLL.dll" ()

Private Sub M1()
Call qq5
Call qq6
End Sub


这是 Excel 2007 的VBA中运行效果截图:
bobogg 2015-07-20
  • 打赏
  • 举报
回复
引用 118 楼 Chen8013 的回复:
问题多半是出在你的代码编写,或者这个dll只能在exe中调用。 这个dll只能用于exe来调用,它就不能用于vba环境。
vb6_ide --> 成功 vb6_exe --> 成功 vba --> 死机 目前看来原因是不能用于 vba 只是原因是什么呢? 想不出ㄟ
舉杯邀明月 2015-07-20
  • 打赏
  • 举报
回复
引用 117 楼 Bobogg 的回复:
报告 Chen8013 楼主 用你的程序编译的 StdDLL 实验如下 (1) 在 VB6 下执行 --> 成功 (2) 在 EXCEL Vba 下执行 --> 失败, EXCEL 死机 --> 不知程序能修正吗
我的这个工具,已经有更新的了。 请看看新帖子的说明: http://bbs.csdn.net/topics/390976419 最新的版本(Ver2.01): http://download.csdn.net/detail/chen8013/8876897
舉杯邀明月 2015-07-20
  • 打赏
  • 举报
回复
引用 117 楼 Bobogg 的回复:
报告 Chen8013 楼主 用你的程序编译的 StdDLL 实验如下 (1) 在 VB6 下执行 --> 成功 (2) 在 EXCEL Vba 下执行 --> 失败, EXCEL 死机 --> 不知程序能修正吗
VB6的部分功能,只能在“编译后的exe”中调用。 基本上可以这么说: 如果能编译通过并链接出dll,那么“使用时”有问题,这些“问题”都与我的工具无关。 问题多半是出在你的代码编写,或者这个dll只能在exe中调用。 我的工具是不干涉编译过程的,也不会去调整它的实现、运行机制。 仅仅是在“链接过程”中进行了拦截处理,重新“指导”它按需要把obj文件链接成dll文件(本来它是链接成exe的)。 你可以试一下(在dll代码没问题的情况下),如果在VB6的IDE中运行正常,那么VBA就应该能用; 否则(比如会造成VB6崩溃、或VB6报错等),这个dll只能用于exe来调用,它就不能用于vba环境。
加载更多回复(108)
吸取前辈的经验,自己写了个VB6.0 DLL文件的编译链接插件,按照以下方法,可以在VB 6.0中直接编译生成带外部输出的DLL文件。   1. 把MakeDLL.dll和MakeDLL.exe两个文件复制入VB所在目录,例如   "C:\Program Files\Microsoft Visual Studio\VB98"   2. 把Module1DLL.bas和Standard DLL.vbp两个文件复制入VB所在目录下的   Template目录下的Projects目录,例如   "C:\Program Files\Microsoft Visual Studio\VB98\Template\Projects"   3. 启动VB 6.0,随便选择建立一种什么类型的程序,然后主菜单选择"外接程序"   再选择"外接程序管理器",你应该可以看到在列表中有"Create DLLs in VB 6.0,然后选择它,并在窗口右下方的"加载行为"中把"在启动中加载"和"加载/卸载"都钩选,点确定,再次关闭VB 6.0   4. 再次启动VB,建立一个ActiveX DLL程序,这个时候点主菜单"文件",可以看到"生成工程1.DLL(K)"和"选择DLL出口函数"菜单项目。   好了,大功告成,现在你的VB 6.0已经可以直接编译链接标准DLL文件了,造作方法,如下:   建立ActiveX dll程序,添加一个模块(DLL的函数只能在模块中才有效),在模块中编写你的DLL function过程函数,编写完毕,点保存,然后点"文件"菜单下的”选择DLL出口函数",在弹出窗口中选择需要申明为可以外部调用的   function,然后确定,最后点"文件"->"生成xxx.dll(K)",编译生成DLL。   需要注意的地方如下:   1. 程序代码必须在模块中编写   2. 需要申明为外部调用的函数必须为Public   3. DLL代码中必须包含一个function DLLmain函数和一个sub Main,不过function DLLmain会被执行,而sub main只是摆设,其中的代码不会运行,但是必须有这个东西(◎_◎)。   4. DLL代码编写没有什么特殊的要求,可以做一切可以在VB中用的东西,比如调用API啊,编写嵌入代码啊(关键)……

1,066

社区成员

发帖
与我相关
我的任务
社区描述
VB 资源
社区管理员
  • 资源
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧