原理:
Visual Basic 从5.0起就可以象C++那样将程序编译成本地码.VB将程序中的每个form, bas, cls, vbp 编译为obj文件,然后再调用连接程序将它们连接成EXE, 这个过程是自动的,连接完成后它会自动删除中介生成的OBJ文件. 要实现我们的目的就需要在连接程序连接输出EXE之前对OBJ文件进行处理,将C++编译的OBJ文件换进去.
准备:
我们需要自己些一个连接程序,当然这个程序不是要实现连接的功能,只需要实现 预先处理 OBJ 文件, 获取VB传递给连接程序的参数, 对参数进行 必要的修改, 然后 调用原连接程序 完成连接工作. 我们将vb目录下的Link.exe 改名为 vblink.exe, 再将我们写的link.exe 放到这个目录中. 这个Fake Link 程序我已经完成了, 在压缩包包中可以找到.
先讲讲这个Fake Link 程序是怎么工作的:
首先 程序取得 VB 传递给连接程序的 参数.
通过对参数进行分析 获取 当前所编译的VB工程文件的完整路径.(如:F:\ LinkWithVC\ LinkWithVC.vbp), 然后程序会查找该工程对应的自定义连接配置文件(F:\LinkWithVC\ LinkWithVC_link.ini), 如果找不到 程序什么也不做直接调用vblink.exe.
如果找到了,就读取里面的设置,按照设置进行相应的处理,最后调用 vblink.exe.
InI文件的配置将在 下面实践测试中做介绍.
实践测试:
运行VB6新建一个工程,工程名设为LinkWithVC, 给工程添加一个模块(bas), 名称设为 ModVC.
给窗体添加一个按钮 名称 cmdTest, 标题 Test. 在ModVC中添加
Public Function Test() As Long
Test = 9
End Function
在cmdTest的Click事件中添加 代码 msgbox test, 保存工程,编译运行,点击按钮我们会看到
是9没错就是 9 .
现在我们启动VC6新建一个空的Win32工程名称就叫vcobj,目录就设置为VB工程LinkWithVC所在的目录.
在工程中添加一个Generic Class ,类的名称就叫ModVC, 设置活动配置为 Win32 release. 现在就点击 Build 菜单中的 Compile ModVC.cpp 将它编译成OBJ文件.
然后在VB工程目录下建一个文件 LinkWithVC_link.ini.在文件中输入如下内容:
[Settings]
lib=0
log=1
[OBJ]
F:\LinkWithVC\vcobj\Release\ModVC.obj=F:\LinkWithVC\ModVC.obj
[lib]
注:F:\LinkWithVC是VB工程所在目录,F:\linkWithVC\vcobj是VC工程所在目录.
Ini文件有三个段.Settings段有lib 它表示 需要附加的lib的数量. 相应的lib在lib段中定义.
OBJ段就是OBJ替换定义段可以是 vc的obj=vb的obj. Fake Link程序会自动用vc的obj替换vb的obj文件.
Log为1表示生成连接记录. 有记录便于排错.
好了现在我们切换到VB工程 来生成LinkWithVC.exe
完了我们会发现并没有生成EXE, 打开log文件看看,会看到如下内容:
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
Form1.OBJ : error LNK2001: unresolved external symbol "private: void __stdcall ModVC::Test(void)" (?Test@ModVC@@AAGXXZ)
F:\LinkWithVC\LinkWithVC.exe : fatal error LNK1120: 1 unresolved externals
看到拉,连接出错了 unresolved external symbol private: void __stdcall ModVC::Test(void) ,这个是正常的,我们替换了ModVC.obj,而我们的VC的modvc.obj并没有定义这个函数.接下来就是解决这个问题了.知道怎么做了吧,…现在切换到VC,在类ModVC中定义一个private的函数void __stdcall Test();函数体先空着.再编译它. 然后切换到VB生成EXE.好了生成了EXE文件了,我们运行它,点击按钮,会看到:
是10不是9,显然替换成功了,可是为什么是10呢…我也不清楚….(:P)
Void的函数怎么返回值呢? 在Windows中 函数返回值一般都是存放在eax中的, 我们来试试.在 Test的函数体中 添加代码 _asm mov eax , 123, 再重复前面的操作生成EXE,运行:
看到了123
代码下载
__hxxp://www.bbsftp.net/UploadFile/LinkWithVC01.rar