欢迎光临 Rick 's BLOG
日志首页  | C# .Net编程  | 原创作品  | 生活点滴  | C\C++相关  | 多媒体相关※ERMP  | VB相关  | 其它运维与编程  |  留言簿
用VB写MOUSE穿透的窗体 VC_VB的混合编译(二)实践进阶片
晴天  VC_VB的混合编译(一) 原理片
[ 发布日期:20年前 (2005-04-07) ]   [ 来自:本站原创 ] [分类:VB相关]
原理:
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是不是很兴奋啊. 不要高兴得太早,返回值解决了,可是怎么给函数传递参数呢?

点击下载此文件
引用通告地址 (0):
复制引用地址https://www.rickw.cn/trackback/65
复制引用地址https://www.rickw.cn/trackback/65/GBK
[ 分类:VB相关  | 查看:3528 ]

引用这个评论  (访客) 于 2005-06-08 19:40:54 发表评论:
引用这个评论  (访客) 于 2005-04-20 14:56:37 发表评论:
如果有能查找DLL和搜索DLL是那个进程的话就完美了!

发表评论
作者:   用户:[访客] 
评论:

表  情
禁止表情 | 禁止UBB | 禁止图片 | 识别链接
对不起,你没有权限上传附件!
验证:
 
PoweredBy R-Blog V1.00 © 2004-2024 WWW.RICKW.CN, Processed in second(s) , 7 queries    京ICP备17058477号-5