首先我来说一下原理:
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只有四个函数:
  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,看最底部:
?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文件”
经过我的研究发现你需要把KERNEL32.LIB、USER32.LIB、LIBC.LIB、UUID.LIB、OLDNAMES.LIB这几个VC++的默认库全部放到你的OBJ文件夹。然后修改BUILD.BAT,在它的最前面LINK的后面加个空格,加上“KERNEL32.LIB USER32.LIB ”然后再次双击BUILD.BAT就会发现链接成功了。
打开EXE,点击上面的四个按钮,它们都正常运行啦~~赞一个