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

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 23143|回复: 30

【混合编程】VB6与VC++的合体编程(不使用DLL)

[复制链接]
发表于 2014-4-3 20:11:16 | 显示全部楼层 |阅读模式

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

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

×
转载请注明出处:http://www.0xaa55.com/thread-445-1-1.html
我觉得这应该是史无前例的。我是先驱者。。膜拜我吧

首先我来说一下原理:
VB6的IDE会把VB的工程编译成OBJ,然后用LINK完成链接。那么最后VB生成的OBJ去哪了呢?其实是被VB的IDE自动删除了。我们要做的就是截取VB还没完成链接的时候VB的IDE产生的OBJ文件,然后把它们和VC++产生的OBJ一起链接,以此来实现合体编程。这个的好处就是VB写界面方便而VC++能做到许多VB做不到的事,两者取长补短,互利共生。

首先打开VB6的IDE的文件夹。可以看到VB的LINK.EXE。VB就是用它完成链接的。
20140403173558.png
这个时候果断自己写一个LINK.EXE换掉这个原先的LINK.EXE!不过先备份旧的LINK.EXE,很简单,直接改名为LINK1.EXE就行了。
然后把自己写的LINK.EXE放进来。自己写的LINK.EXE有个特点,就是,它会卡住!这样我们就能趁它卡住的时候,找到工程文件里面的OBJ文件然后把它复制出来了。
那么我这里提供了一份我自己写的“假LINK.EXE”。压缩包里面有四个文件,两个批命令和两个EXE,这两个EXE一个是真LINK.EXE的备份,一个是假LINK.EXE的备份,双击GENEXE.BAT后就会自动把链接器换成真LINK.EXE,双击GENOBJ.BAT则会自动链接器换成假LINK.EXE。
下载地址:
VBGENOBJ.RAR (200.6 KB, 下载次数: 27)
下载后解压到你的VB的IDE的文件夹里面即可。

好,接下来准备编译得到OBJ。我准备了这么一个工程,它只有一个窗体和一个模块,我们要做的就是把这个模块换成VC++的OBJ,实现合体。
20140402153306.PNG
上图这个工程我会在后面提供下载。
我们要用VC++实现这个模块提供的函数!
那么先开始编译吧。
首先双击GENOBJ.BAT,换上假的链接器。
20140403175033.png
然后打开工程,文件->生成XXX.exe
只见它一卡,然后我们的假LINK就出来了。如下图所示:
20140402153656.PNG
没错!就是这样!我们现在就打开记事本把刚才的链接命令记下来。
20140403184535.png
20140402154250.PNG
看见了吧?这个是OBJ!我们看到了OBJ!
别急。创建OBJ文件夹。把得到的OBJ都丢进去。
20140403162625.png
好的,VB的IDE已经可以不鸟它了,接下来我们需要用VC++写一个代替modCOrCPP.obj的程序。
准备好了吗?
好,我们打开VC++,建立一个新的控制台程序
20140403190917.png
讨厌预编译头,所以把它弄掉。
20140403191212.png
然后我们新建一个modCOrCPP.cpp,如下。
20140403191429.png
接下来就是写代码的部分了。这可是重点!
首先说一下就是VB的OBJ是个什么规律。
大家可以看到modCOrCPP只有四个函数:
  1. Sub VCPPSub()

  2. End Sub

  3. Function VCPPFunction() As Long

  4. End Function

  5. Sub VCPPSubWithParam(ByVal A As Long, ByVal B As Long)

  6. End Sub

  7. Function VCPPFuncWidthParam(ByVal A As Long, ByVal B As Long) As Long

  8. End Function
复制代码
我们只要能用VC++实现这4个函数就行了。
我们用WinHex打开VB生成的modCOrCPP.obj,看最底部:
20140403192457.png
可以看出这个OBJ导出了四个符号:
?VCPPSub@modCOrCPP@@AAGXXZ
?VCPPFunction@modCOrCPP@@AAGXXZ
?VCPPSubWithParam@modCOrCPP@@AAGXXZ
?VCPPFuncWidthParam@modCOrCPP@@AAGXXZ
根据符号修饰我们会发现VB导出的这四个函数的原型其实用VC++是像下面这样的:
  1. class modCOrCPP
  2. {
  3. private:
  4.     void _stdcall VCPPSub(void);
  5.     void _stdcall VCPPFunction(void);
  6.     void _stdcall VCPPSubWithParam(void);
  7.     void _stdcall VCPPFuncWidthParam(void);
  8. };
复制代码
没错,无论你怎么声明,它的原型都是【void _stdcall 类名::私有函数(void);】这种规律的,产生的符号也都是【?函数名@类名@@AAGXXZ】这样的。(我这里解释一下,结尾的“AAGXXZ”的意思是这个函数没有返回值,也没有参数列表,是一个类的私有成员函数,而且是_stdcall风格的)
这样我们怎样获取参数信息呢?只能通过裸函数了。
比如有个VB的函数,它的定义是Function foo() as Long那么它产生的符号翻译成VC++的函数原型就成了void _stdcall 类名::foo(void);
这个时候我们需要做的就是重新写一个函数,然后让这个类的导出函数跳转到这个函数,如下:
  1. static long bar(void)
  2. {
  3.     return 233;//设置返回值
  4. }
  5. _declspec(naked)void 类名::foo()
  6. {
  7.     _asm jmp bar;//直接跳走
  8. }
复制代码
这样就行了。OBJ就能产生同样的符号了。
在VC6的界面下编译modCOrCPP.cpp->modCOrCPP.obj,然后我们在Debug、Release文件夹里面找到这个文件:modCOrCPP.obj,复制到VB的那堆OBJ里面,覆盖掉原先的OBJ文件,嗯,还记得之前打开过的记事本吧?

在这一整行链接器命令的前面加上一个“LINK ”,再把所有要链接的OBJ文件的文件路径去掉只保留文件名,在这整行命令的结尾按下回车,打个“@pause”,然后保存到你的OBJ文件夹,存为“BUILD.BAT文件”
20140403195940.png
20140403195331.png
还没完呢,接下来大家需要找到原先的VB的LINK.EXE和它所依赖的MSPDB60.DLL,把它们一起放到你的OBJ文件夹里面。
20140403195528.png
20140403195620.png
接下来双击BUILD.BAT,发现好像缺少了一些LIB。这个时候果断去VC++的Lib文件夹里面找到需要的LIB放到工程文件夹。
20140403200326.png
经过我的研究发现你需要把KERNEL32.LIB、USER32.LIB、LIBC.LIB、UUID.LIB、OLDNAMES.LIB这几个VC++的默认库全部放到你的OBJ文件夹。然后修改BUILD.BAT,在它的最前面LINK的后面加个空格,加上“KERNEL32.LIB USER32.LIB ”然后再次双击BUILD.BAT就会发现链接成功了。
打开EXE,点击上面的四个按钮,它们都正常运行啦~~赞一个
20140403200752.png
20140403200719.png
最后给出各种下载地址。
全部工程下载:
游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

发表于 2014-4-3 21:54:25 | 显示全部楼层
以后就可以吧vb程序变成vc的了
回复 赞! 靠!

使用道具 举报

发表于 2014-4-11 12:20:00 | 显示全部楼层
看到了C 艹
回复

使用道具 举报

发表于 2014-4-19 13:08:37 | 显示全部楼层
这样合体后的VC程序,是不是还是需要VB的运行库?
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2014-4-19 18:36:00 | 显示全部楼层
0x0208 发表于 2014-4-19 05:08
这样合体后的VC程序,是不是还是需要VB的运行库?

对。是不是觉得略操蛋了点儿
回复 赞! 靠!

使用道具 举报

发表于 2014-4-20 10:38:12 | 显示全部楼层
0xAA55 发表于 2014-4-19 18:36
对。是不是觉得略操蛋了点儿

忙活半天,它不还是VB。
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2014-4-20 15:08:08 | 显示全部楼层
0x0208 发表于 2014-4-20 02:38
忙活半天,它不还是VB。

你要这么说也行,但是你也可以说它是C、C艹
回复 赞! 靠!

使用道具 举报

发表于 2016-6-3 18:05:33 | 显示全部楼层
这个实在是有意思~~
回复 赞! 靠!

使用道具 举报

发表于 2017-3-29 18:01:01 | 显示全部楼层
原来就是中断link啊。。。那能不能自己通过批处理或命令行直接调用c2来编译vb的代码呢?
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2017-3-29 19:27:05 | 显示全部楼层
tangptr@126.com 发表于 2017-3-29 18:01
原来就是中断link啊。。。那能不能自己通过批处理或命令行直接调用c2来编译vb的代码呢? ...

那是中断c2,你要做啥?
回复 赞! 靠!

使用道具 举报

发表于 2017-3-30 12:46:50 | 显示全部楼层
0xAA55 发表于 2017-3-29 19:27
那是中断c2,你要做啥?

C2难道不是把vb代码编译到obj的玩意么。。。
回复 赞! 靠!

使用道具 举报

发表于 2017-3-30 18:38:42 | 显示全部楼层
谢谢分享
回复

使用道具 举报

发表于 2017-10-23 18:16:42 | 显示全部楼层
这个看不懂,但是觉得很高级
回复 赞! 靠!

使用道具 举报

发表于 2017-10-25 02:26:22 | 显示全部楼层
MARK,有时间研究研究
回复 赞! 靠!

使用道具 举报

发表于 2017-11-3 08:32:03 | 显示全部楼层
厉害
回复

使用道具 举报

发表于 2017-11-17 14:21:02 | 显示全部楼层
学习了,谢谢分享。
回复 赞! 靠!

使用道具 举报

发表于 2017-12-24 15:28:50 | 显示全部楼层
这个感觉听着有可行性,目前正适合我的需要
回复 赞! 靠!

使用道具 举报

发表于 2018-4-23 12:42:37 | 显示全部楼层
这个可以增加我装逼的词库量
回复 赞! 靠!

使用道具 举报

发表于 2018-6-9 08:29:39 | 显示全部楼层
膜拜,学习一下
回复 赞! 靠!

使用道具 举报

发表于 2018-6-15 16:02:07 | 显示全部楼层
下个文件就走
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-21 21:11 , Processed in 0.048774 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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