首页
社区
课程
招聘
[原创]VC_VB的混合编译
发表于: 2005-10-18 16:25 14396

[原创]VC_VB的混合编译

2005-10-18 16:25
14396

原理:
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


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (11)
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
2
不错,下载下来试试。
2005-10-18 16:54
0
雪    币: 117
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
真的可以?我试试
2005-10-19 16:48
0
雪    币: 233
活跃值: (130)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
4
学习啊
2005-10-19 17:25
0
雪    币: 61
活跃值: (160)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
5
2005-10-22 12:16
0
雪    币: 6
活跃值: (80)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
想试试,没看到有代码下载啊
2009-8-31 22:24
0
雪    币: 32
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
恩 学习了 好知识
2009-9-1 00:25
0
雪    币: 6
活跃值: (80)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
老大,怎么用啊,没代码
2009-9-7 19:00
0
雪    币: 23
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
好复杂啊  看晕了
2009-9-7 20:56
0
雪    币: 207
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
还看不太懂,学习。
2009-9-26 17:21
0
雪    币: 403
活跃值: (29)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
11
向楼主学习致敬!
2009-9-26 19:01
0
雪    币: 261
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
学习一下 谢谢
2009-10-4 13:58
0
游客
登录 | 注册 方可回帖
返回
//