欢迎光临 Rick 's BLOG
日志首页  | C# .Net编程  | 原创作品  | 生活点滴  | C\C++相关  | 多媒体相关※ERMP  | VB相关  | 其它运维与编程  |  留言簿
VC_VB的混合编译(一) 原理片 C语言中可变参数的用法
晴天  VC_VB的混合编译(二)实践进阶片
[ 发布日期:20年前 (2005-04-07) ]   [ 来自:本站原创 ] [分类:VB相关]
在上一回我们已经实现VC,VB代码的混合编译,并成功的在VB代码中调用了VC代码中的一个无参数的函数,并取得了函数的返回值. 这一回我们将实践一下如何调用带参数的函数.
打开上一会的两个工程(LinkWithVC, vcobj). 切换到VB在form上添加一个按钮 name: cmdTestLong, 标题 TestLong. 在form上添加一个文本框txtInput 内容填 8. 再在ModVC中添加如下代码:
Public Function TestLong(ByVal lng As Long) As Long
TestLong = -1
End Function
在cmdTestLong的Click事件中添加代码 msgbox Testlong(clng(txtInput.Text))
现在我们来生成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::TestLong(void)" (?TestLong@ModVC@@AAGXXZ)
F:\LinkWithVC\LinkWithVC.exe : fatal error LNK1120: 1 unresolved externals
看到了吗,和第一次看到的错误Log除了函数名,完全是一样的……这时候想到了什么? 参数呢? 在VB代码中明明是有参数申明的啊? ….先不管它, 和上回一样在VC类中添加一个名为TestLong的同类型的空函数. 编译vc的obj,再生成VB的EXE,运行点击 TestLong按钮, 我们看到msgbox提示8, 和我们的参数8 一样!! 是巧合? 试试 改改 txtInput 中的数字. 再点击TestLong按钮. 我们会发现 msgbox提示的和txtInput文本框中的数字是一样的. 有了上回返回值的经验, 而我们的函数什么也没有做, 如是我们会知道 这个参数就 是存放在 eax中的, 好了到了这里 我们知道怎么在VC代码中获取 vb代码传递的参数了. 可是在传递一个 long 型的数据 有什么实际用途呢?  一个 long 它就意味着 一个长整形数字、一个句柄、一个指针….我们来看一个实际的例子。
在Form上添加一个按钮cmdTestHwnd在按钮 TestHwnd的 Click事件中添加代码 call TestLong(txtInput.hWnd)
这里我们传递的是一个textbox的句柄。
我在VC函数中添加如下代码
void ModVC::TestLong()
{
long hw;
_asm mov hw,eax; //取得参数(TextBox的句柄)
SetWindowText((HWND)hw,"VC: Hello VB");

}
重复操作,生成我们的EXE,。。。我们会发现失败了,打开log看看。
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

ModVC.OBJ : error LNK2001: unresolved external symbol __imp__SetWindowTextA@8
F:\LinkWithVC\LinkWithVC.exe : fatal error LNK1120: 1 unresolved externals
熟悉VC的一看就知道连接的时候没有把User32.lib连接进去。
解决方法有两个1个是在VC代码中使用LoadLibray,GetProcessAddress的方式调用这个api,另一个方法就是 让连接器 把user32.Lib连接进去。 显然如果要大量使用api函数的话第一中方法太繁琐。我们用第二个方法。怎么做了呢?还记得上一回的 自定义连接配置文件吗。
[Settings]
lib=1
log=1

[OBJ]
F:\LinkWithVC\vcobj\Release\ModVC.obj=F:\LinkWithVC\ModVC.obj

[lib]
1=User32.lib
Settings段的lib 表示 [lib]段中的lib数目。 在lib段 我按照顺序1=…,2=… 添加我们要连接的lib即可,当然也可以是obj文件。
好我们再来操作,生成EXE,OK。运行点击TestHwnd。好了我们看到TextBox中的文字变成了 VC: Hello VB 。
我们再来试试字符串。
在form上添加一个按钮TestString 在ModVC中添加函数
Public Function TestString(ByVal s As String) As Long
Rem nothing
End Function
TestString的Click事件中添加如下代码
Private Sub CmdTestString_Click()
Dim s As String
s = Space(256) '为s分配空间
Call TestString(s)
MsgBox s
End Sub
在VC中添加同名函数
void ModVC::TestString()
{
char* p;
_asm mov p,eax; //取得参数(TextBox的句柄)
memset(p,0,256);//我们知道字符串的长度是256
lstrcpy(p,"VC: Hello VB");

}
编译,生成EXE,运行,点击TestString按钮,。。。咦,显示的是乱码!!??这是因为VB中的String用的是Unicode,VC中复制的不是。转一下就可以了。就在vb中转吧vb有一个函数很方便。把msgbox s 改为 MsgBox StrConv(s, vbUnicode),再生成EXE运行,这次OK了。
接下来我们再试试传递结构体。函数参数格式的声明我们可以参考一下VB中API函数的声明。我来个简单点的结构体 POINTAPI, 用VB的 API Viewer 找到
Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long

Public Type POINTAPI
        x As Long
        y As Long
End Type
参这个我们在ModVC中添加函数
Public Function TestStruct(lppt As POINTAPI) As Long
Rem
End Function
在form上添加一个按钮TestStruct,在Click中添加代码
Private Sub cmdTestStruct_Click()
Dim pt As POINTAPI
Call TestStruct(pt)
MsgBox "x= " & pt.x & " y=" & pt.y
End Sub
在VC类中添加同名同类型函数。
void ModVC::TestStruct()
{
POINT *pt;
_asm mov pt,eax;//获取 指针参数
pt->x = 123;
pt->y = 456;
}
编译运行。。。。我们会发现 非法操作。大概是说引用了0x00000000处的内存。看这个内存地址我们会知道 在vc中引用了一个空指针,那就是说eax的值是0。那则么回事参数没有在eax里面,参数跑哪里去了?在其它寄存器?不太可能。。。那会在哪里呢,我们总不能凭空变出来一个参数吧。想想C++类中有什么可以用的符号?嗯,有一个 this 指针。会是它吗,熟悉VC的人应该知道在调用类成员函数时会先将该类的this指针存放到 eax 中。看来他们有很大的关系。那就动手试试。函数改为如下:
void ModVC::TestStruct()
{
POINT *pt=(POINT)this;
pt->x = 123;
pt->y = 456;
}
再编译,生成EXE运行。OK!成功了,看到了 x= 123 y=456 .
我们再回过头来看看前面的函数 ,都假设把this 当着参数试试,经过测试假设成立。如是我们知道this 就是传递过来的参数,当参数是long是,同时eax中也有这个参数值的一个副本。
到现在看来似乎是大功告成了,还没有!还有一个难题,this就只有一个,如果要传递2个,3个,4个。。。参数怎么办呢?

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

暂时没有评论,快来发表一个评论吧。
发表评论
作者:   用户:[访客] 
评论:

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