技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 10207|回复: 15
收起左侧

【VB6】使用VB6写“标准DLL”

[复制链接]

1099

主题

1600

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
242
威望
681 点
宅币
23204 个
贡献
46153 次
宅之契约
0 份
在线时间
2207 小时
注册时间
2014-1-26
发表于 2017-4-6 08:38:33 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

x
为啥要加双引号呢?因为DLL就是DLL,没啥标准不标准的说法。这里只不过有些人认为,带COM组建的DLL就不是“标准DLL”。
方法很简单,写个假的链接器,使用它来修改链接命令,然后插入想要导出的函数就可以了。
其实这就是一个简单的编译原理的知识,或者说是“链接器原理”。献给所有喜爱编程的初学者。

VB6导出“标准DLL”(也就是不带COM类的DLL)的方法无非就是把链接器的参数改一下就好。VB6本身生成的obj和VC6的格式差不多,因为都是nasm所说的“win32”格式,所以其实VB6使用的链接器和VC6的是一样的。链接器就负责将一堆obj或者lib组合起来,生成dll或者exe。所以VB6也能生成“标准DLL”。
因为VB6默认没有“标准DLL”工程,所以大家都以为VB6不能生成“标准DLL”。但其实我们自己修改VB6的链接器参数就可以实现生成“标准”DLL。
这个的解决方案很简单。自己写一个假的链接器,用于修改命令行参数,然后把修改了的命令行参数传达给真正的链接器即可。假的链接器的写法也可以很随意。反正实现了功能就好。

我这边写了一个。它的规则是:当你的工程里面有一个叫“DLL_Module”的模块(或frm、res、cls等都会被识别)的时候,就会把当前工程认定为DLL工程,然后查找工程目录下的Dll_Module.def(模块定义文件)。如果你没有这个文件的话,它就会提示你创建这个文件(它会创建给你并自动帮你用记事本打开这个文件)。

PseudoLinker(伪链接器)下载(包含工程和源码,还有编译好的BIN):
pseudolinker.zip (10.34 KB, 下载次数: 93)

运行BIN的时候请注意安全:
校验信息
名称: LINK.EXE
大小: 36864 字节 (36 KiB)
SHA256: 73975F6C944159B0A4A0E81EC4D0431F15CC5541134C5AD8C522FB8C722ED893

伪链接器用法:
1、进自己的VB6安装目录(我的是 C:\Program Files (x86)\Microsoft Visual Studio\VB98
2、找到LINK.EXE,将其改名为“ORG_LINK.EXE”
3、把我写的伪链接器LINK.EXE复制进去。搞定。
20170406092435.png

安装好这个伪链接器后,你就能写DLL工程了。写法很简单,创建一个空工程,添加一个模块,改名为DLL_Module,然后保存为DLL_Module.bas。
模块的内容有一部分内容是需要写的。这里示范了如何写一个导出函数“foo”的例子。
[Visual Basic] 纯文本查看 复制代码
Option Explicit

Public Const DLL_PROCESS_DETACH As Long = 0
Public Const DLL_PROCESS_ATTACH As Long = 1
Public Const DLL_THREAD_ATTACH As Long = 2
Public Const DLL_THREAD_DETACH As Long = 3

Sub Main()
' 留空
End Sub

Public Function DllMain(ByVal hInst As Long, ByVal fdwReason As Long, ByVal lpvReserved As Long) As Boolean
   Select Case fdwReason
      Case DLL_PROCESS_DETACH
         
      Case DLL_PROCESS_ATTACH
         DllMain = True
      Case DLL_THREAD_ATTACH
         
      Case DLL_THREAD_DETACH
         
   End Select
End Function

Function foo(ByVal A As Long, ByVal B As Long) As Long
foo = A + B
End Function
20170406085007.png

其中DllMain是DLL入口,Sub Main是EXE入口,保留Sub Main是为了让VB6能允许你编译它。能编译就能得到OBJ,能得到OBJ就能链接,能链接就能生成DLL。

然后,试着编译了一下,嗯因为之前我们没写DEF文件,这里果然提示了要创建DEF文件。
20170406084603.png

然后记事本弹出来了。此时修改DEF文件,添加我们要导出的函数名。
20170406084807.png

保存后,再次编译,没有意外的话应该就能成功获得DLL、EXP、LIB三个文件了。
20170406085045.png

而且它也确实导出了foo这个函数。
20170406092203.png

嗯但关键是这个DLL要别的语言也能用哈。有人跟我这样说。我只想表示,蛤?我都做出DLL了你还担心别的语言不能用?编译原理都不懂就瞎说,明明是自己无知。

来创建测试工程。废话不啰嗦,先把DLL丢输出目录,然后开始编码。
之前VB写的foo函数原型是 Function foo(ByVal A As Long, ByVal B As Long) As Long ,那么它的C语言原型应该是long _stdcall foo(long A, long B);

看。
20170406093106.png

这是编译成功的标志。事实上它运行也是成功的:
20170406093147.png

不过话说回来,我们为啥要用VB6写DLL呢?

参考阅读:
【混合编程】VB6与VC++的合体编程(不使用DLL)

本帖被以下淘专辑推荐:

回复

使用道具 举报

0

主题

3

回帖

25

积分

用户组: 初·技术宅

UID
2307
精华
0
威望
0 点
宅币
22 个
贡献
0 次
宅之契约
0 份
在线时间
2 小时
注册时间
2017-3-7
发表于 2017-4-6 08:58:53 | 显示全部楼层
这个够详细 先顶 再试试

85

主题

175

回帖

3988

积分

用户组: 管理员

No. 418

UID
418
精华
14
威望
53 点
宅币
1974 个
贡献
1578 次
宅之契约
0 份
在线时间
252 小时
注册时间
2014-8-9
发表于 2017-4-6 13:30:15 | 显示全部楼层
不过话说回来,我们为啥要用VB6写DLL呢?

因为:“又能了解链接器原理啦,老开心的!”
In the beginning I was not the best.
And the world was also not the best.
But I still know that I am who I am.
Because I think that it is good.
I have been working hard.
I have been keeping growth with the world.
And it was so.

52

主题

231

回帖

8973

积分

用户组: 管理员

UID
77
精华
16
威望
237 点
宅币
7890 个
贡献
246 次
宅之契约
0 份
在线时间
229 小时
注册时间
2014-2-22
发表于 2017-4-6 14:49:02 | 显示全部楼层
学习了!不过如果这种DLL里带界面,似乎就不能正常使用了。

1099

主题

1600

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
242
威望
681 点
宅币
23204 个
贡献
46153 次
宅之契约
0 份
在线时间
2207 小时
注册时间
2014-1-26
 楼主| 发表于 2017-4-6 18:56:20 | 显示全部楼层
美俪女神 发表于 2017-4-6 14:49
学习了!不过如果这种DLL里带界面,似乎就不能正常使用了。

好像是,估计得找个机会跑一次__vbaS

2

主题

12

回帖

76

积分

用户组: 小·技术宅

UID
1432
精华
0
威望
2 点
宅币
58 个
贡献
0 次
宅之契约
0 份
在线时间
8 小时
注册时间
2016-1-21
发表于 2017-4-13 17:51:53 | 显示全部楼层
来支持 一下,连接器还能写C代码 汇编代码。只是VB 多变却兼容性不足罢了。。。

1099

主题

1600

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
242
威望
681 点
宅币
23204 个
贡献
46153 次
宅之契约
0 份
在线时间
2207 小时
注册时间
2014-1-26
 楼主| 发表于 2017-4-14 14:09:40 | 显示全部楼层
0xAA66 发表于 2017-4-13 17:51
来支持 一下,连接器还能写C代码 汇编代码。只是VB 多变却兼容性不足罢了。。。
...

链接器并不能写代码,它只负责链接

2

主题

12

回帖

76

积分

用户组: 小·技术宅

UID
1432
精华
0
威望
2 点
宅币
58 个
贡献
0 次
宅之契约
0 份
在线时间
8 小时
注册时间
2016-1-21
发表于 2017-4-15 17:14:10 | 显示全部楼层
0xAA55 发表于 2017-4-14 14:09
链接器并不能写代码,它只负责链接

意思就是说,把连C的代码给连接起来。一起编译。这样就能伪C代码 写在VB中。

1099

主题

1600

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
242
威望
681 点
宅币
23204 个
贡献
46153 次
宅之契约
0 份
在线时间
2207 小时
注册时间
2014-1-26
 楼主| 发表于 2017-4-15 19:26:50 | 显示全部楼层
0xAA66 发表于 2017-4-15 17:14
意思就是说,把连C的代码给连接起来。一起编译。这样就能伪C代码 写在VB中。 ...

那也不是“伪C代码”,那是组合语言编程

59

主题

109

回帖

1万

积分

用户组: 超级版主

OS与VM研究学者

UID
1043
精华
33
威望
751 点
宅币
7479 个
贡献
1053 次
宅之契约
0 份
在线时间
1780 小时
注册时间
2015-8-15
发表于 2018-2-10 22:36:24 | 显示全部楼层
这样生成出来的lib文件应该也可以放进EXE的链接器参数里吧,然后直接在头上声明函数原型实现导入

0

主题

20

回帖

10

积分

用户组: 初·技术宅

UID
3807
精华
0
威望
0 点
宅币
-10 个
贡献
0 次
宅之契约
0 份
在线时间
5 小时
注册时间
2018-5-5
发表于 2018-5-6 07:31:24 | 显示全部楼层
要是加上导出后自动生成导出函数声明的.那就有方便

51

主题

31

回帖

648

积分

用户组: 大·技术宅

UID
3260
精华
7
威望
12 点
宅币
506 个
贡献
1 次
宅之契约
0 份
在线时间
23 小时
注册时间
2017-12-26
发表于 2018-6-10 19:10:20 | 显示全部楼层
QQ图片20180610190816.png

29

主题

313

回帖

1704

积分

用户组: 上·技术宅

UID
3808
精华
11
威望
105 点
宅币
932 个
贡献
165 次
宅之契约
0 份
在线时间
400 小时
注册时间
2018-5-6
发表于 2018-6-11 09:00:30 | 显示全部楼层
tangptr@126.com 发表于 2018-2-10 22:36
这样生成出来的lib文件应该也可以放进EXE的链接器参数里吧,然后直接在头上声明函数原型实现导入 ...

应该也可以吧,这里运行时获取dll导出函数地址来调用可以,那导入lib再调用也可以应该
Passion Coding!

1

主题

62

回帖

333

积分

用户组: 中·技术宅

UID
6035
精华
0
威望
2 点
宅币
266 个
贡献
0 次
宅之契约
0 份
在线时间
29 小时
注册时间
2020-7-7
发表于 2020-7-8 10:07:32 | 显示全部楼层
本帖最后由 china_shy_wzb 于 2020-7-20 13:43 编辑

学习用VB6写DLL,受教了

0

主题

48

回帖

67

积分

用户组: 小·技术宅

UID
8099
精华
0
威望
2 点
宅币
15 个
贡献
0 次
宅之契约
0 份
在线时间
9 小时
注册时间
2022-10-22
发表于 2022-11-18 16:36:16 | 显示全部楼层
终于知道原理了,其实只要vb工程较大,编译时在文件资源管理器就能看到obj的文件,只不过最后删除了

1099

主题

1600

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
242
威望
681 点
宅币
23204 个
贡献
46153 次
宅之契约
0 份
在线时间
2207 小时
注册时间
2014-1-26
 楼主| 发表于 2022-11-18 21:53:58 | 显示全部楼层
imr2013 发表于 2022-11-18 16:36
终于知道原理了,其实只要vb工程较大,编译时在文件资源管理器就能看到obj的文件,只不过最后删除了 ...

写个假的 link.exe 就可以趁机复制 obj 备份一下。

本版积分规则

QQ|申请友链||Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2023-2-5 21:59 , Processed in 0.046725 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表