首先我来说一下原理:
VB6的IDE会把VB的工程编译成OBJ,然后用LINK完成链接。那么最后VB生成的OBJ去哪了呢?其实是被VB的IDE自动删除了。我们要做的就是截取VB还没完成链接的时候VB的IDE产生的OBJ文件,然后把它们和VC++产生的OBJ一起链接,以此来实现合体编程。这个的好处就是VB写界面方便而VC++能做到许多VB做不到的事,两者取长补短,互利共生。
首先打开VB6的IDE的文件夹。可以看到VB的LINK.EXE。VB就是用它完成链接的。
这个时候果断自己写一个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。
下载地址:
接下来就是写代码的部分了。这可是重点!
首先说一下就是VB的OBJ是个什么规律。
大家可以看到modCOrCPP只有四个函数:
-
Sub VCPPSub()
-
-
End Sub
-
-
Function VCPPFunction() As Long
-
-
End Function
-
-
Sub VCPPSubWithParam(ByVal A As Long, ByVal B As Long)
-
-
End Sub
-
-
Function VCPPFuncWidthParam(ByVal A As Long, ByVal B As Long) As Long
-
-
End Function
复制代码
我们只要能用VC++实现这4个函数就行了。
我们用WinHex打开VB生成的modCOrCPP.obj,看最底部:
?VCPPSub@modCOrCPP@@AAGXXZ
?VCPPFunction@modCOrCPP@@AAGXXZ
?VCPPSubWithParam@modCOrCPP@@AAGXXZ
?VCPPFuncWidthParam@modCOrCPP@@AAGXXZ
根据符号修饰我们会发现VB导出的这四个函数的原型其实用VC++是像下面这样的:
-
class modCOrCPP
-
{
-
private:
-
void _stdcall VCPPSub(void);
-
void _stdcall VCPPFunction(void);
-
void _stdcall VCPPSubWithParam(void);
-
void _stdcall VCPPFuncWidthParam(void);
-
};
复制代码
没错,无论你怎么声明,它的原型都是【
void _stdcall
类名
::
私有函数
(
void
);
】这种规律的,产生的符号也都是【?函数名@类名@@AAGXXZ】这样的。(我这里解释一下,结尾的“AAGXXZ”的意思是这个函数没有返回值,也没有参数列表,是一个类的私有成员函数,而且是_stdcall风格的)
这样我们怎样获取参数信息呢?只能通过裸函数了。
比如有个VB的函数,它的定义是Function foo() as Long那么它产生的符号翻译成VC++的函数原型就成了void _stdcall 类名::foo(void);
这个时候我们需要做的就是重新写一个函数,然后让这个类的导出函数跳转到这个函数,如下:
-
static long bar(void)
-
{
-
return 233;//设置返回值
-
}
-
_declspec(naked)void 类名::foo()
-
{
-
_asm jmp bar;//直接跳走
-
}
复制代码
这样就行了。OBJ就能产生同样的符号了。
在VC6的界面下编译modCOrCPP.cpp->modCOrCPP.obj,然后我们在Debug、Release文件夹里面找到这个文件:modCOrCPP.obj,复制到VB的那堆OBJ里面,覆盖掉原先的OBJ文件,嗯,还记得之前打开过的记事本吧?
在这一整行链接器命令的前面加上一个“LINK ”,再把所有要链接的OBJ文件的文件路径去掉只保留文件名,在这整行命令的结尾按下回车,打个“@pause”,然后保存到你的OBJ文件夹,存为“BUILD.BAT文件”
经过我的研究发现你需要把KERNEL32.LIB、USER32.LIB、LIBC.LIB、UUID.LIB、OLDNAMES.LIB这几个VC++的默认库全部放到你的OBJ文件夹。然后修改BUILD.BAT,在它的最前面LINK的后面加个空格,加上“KERNEL32.LIB USER32.LIB ”然后再次双击BUILD.BAT就会发现链接成功了。
打开EXE,点击上面的四个按钮,它们都正常运行啦~~赞一个