| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1076 人关注过本帖
标题:问个VB6 -> C (ByRef ByVal) 基础的问题
只看楼主 加入收藏
yz1025
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:6
帖 子:491
专家分:919
注 册:2012-10-26
结帖率:95.56%
收藏
已结贴  问题点数:20 回复次数:3 
问个VB6 -> C (ByRef ByVal) 基础的问题
最近遇到个BUG,搞了3天不断的尝试修改VC6代码,使用不同的写法,最后发现是因为VB6写久了,忽视了变量型态声明的重要性,和编译器
对型态定义不同,尤其是VB6到VC6的参数传递,以至于出现各式各样,千奇百怪的结果。因此想问问,如果在VC6写了个DLL,VB6去呼叫来用
时,当参数型态和传递方式不同时,VB6和VC6在内存的配置是怎么个运作法?

虽然透过同事的协助,已经从结果推论原因了,但是还是想听听专业的说法。

VB6:
-----------------------------------------------------------------------------------------------------------------------------------------------------
'1
Public Declare Function DataReSet Lib "DataReSet.dll" (ByVal opt1 As Integer, ByVal opt2 As Integer, ByVal F1 As String, ByVal F2 As String) As Long
Dim label as Integer,Rate as Integer
label =1:Rate =1
MaxLine = DataReSet(label, Rate, File, Temp1)
-----------------------------------------------------------------------------------------------------------------------------------------------------
'2
Public Declare Function DataReSet Lib "DataReSet.dll" (ByRef opt1 As Integer, ByRef opt2 As Integer, ByVal F1 As String, ByVal F2 As String) As Long
Dim label as Integer,Rate as Integer
label =1:Rate =1
MaxLine = DataReSet(label, Rate, File, Temp1)
-----------------------------------------------------------------------------------------------------------------------------------------------------
'3
Public Declare Function DataReSet Lib "DataReSet.dll" (ByVal opt1 As Long, ByVal opt2 As Long, ByVal F1 As String, ByVal F2 As String) As Long
Dim label as Long,Rate as Long
label =1:Rate =1
MaxLine = DataReSet(label, Rate, File, Temp1)
-----------------------------------------------------------------------------------------------------------------------------------------------------
'4
Public Declare Function DataReSet Lib "DataReSet.dll" (ByRef opt1 As Long, ByRef opt2 As Long, ByVal F1 As String, ByVal F2 As String) As Long
Dim label as Long,Rate as Long
label =1:Rate =1
MaxLine = DataReSet(label, Rate, File, Temp1)
-----------------------------------------------------------------------------------------------------------------------------------------------------
'5
Public Declare Function DataReSet Lib "DataReSet.dll" (ByVal opt1 As Long, ByVal opt2 As Long, ByVal F1 As String, ByVal F2 As String) As Long
MaxLine = DataReSet(1, 1, File, Temp1)
-----------------------------------------------------------------------------------------------------------------------------------------------------
'6
Public Declare Function DataReSet Lib "DataReSet.dll" (ByRef opt1 As Long, ByRef opt2 As Long, ByVal F1 As String, ByVal F2 As String) As Long
MaxLine = DataReSet(1, 1, File, Temp1)
-----------------------------------------------------------------------------------------------------------------------------------------------------

针对opt1(label)和opt2(Rate)两参数使用INT型态和Long型态和ByVal和ByRef,和直接指定1,6种模式交叉使用后的内存配置,
和到VC6取得的opt1和opt2的内存读取实际上的步骤有什么不同。

VC6:
int _stdcall DataReSet(int,int,char*,char*);

经过这次以后用VB6要尽量少用Integer型态的变量声明。才不会再遇到这种鸟事。
搜索更多相关主题的帖子: 专业 编译器 
2012-12-26 12:31
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4947
专家分:30084
注 册:2008-10-15
收藏
得分:20 
好像是这样的。
VB6 里,整形是  二个字节。 相当于 VC6 里的 短整形
VB6 里的 长整形(long ) 占4个字节,相当于 VC6 里的整形。

对于 VC6 里的 其它数据类型,就不记得了。 8 字节的 整形,VB6 是不支持的。
但VB6 里有一 定点数,就是货币形 ,忘了占几字节了。

VC6 的整形数据,是与 计算机的字长有关。所以是 32位,4字节。
VB6 的整形数据,是与 兼容 有关,一直都是 2字节。

授人于鱼,不如授人于渔
早已停用QQ了
2012-12-26 12:58
yz1025
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:6
帖 子:491
专家分:919
注 册:2012-10-26
收藏
得分:0 
回复 2楼 风吹过b
这次怪在ByVal模式下使用变量存1(label =1:Rate =1)丢过去C,C接收到的(opt1 opt2)不一定是1
但是如果不用变量,直接输入1丢过去C,接收到的(opt1 opt2)就一定是1
这样就等于完全无视API声明中的参数型态定义
Public Declare Function DataReSet Lib "DataReSet.dll" (ByVal opt1 As Integer, ByVal opt2 As Integer, ByVal F1 As String, ByVal F2 As String) As Long

[ 本帖最后由 yz1025 于 2012-12-26 17:10 编辑 ]

不要投我
2012-12-26 17:06
yz1025
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:6
帖 子:491
专家分:919
注 册:2012-10-26
收藏
得分:0 
而C的部分也怪怪的,虽然已知C的INT比VB6的INT大2个字节,
但是接收VB6 INT参数时是先开2个字节再往高位元再开2个字节,
一直以为开位址是往后开,结果实际上是往前开,
从C接收到的直反推VB6传1时,C是接收到
?? ?? 00 01
而不是
00 01 ?? ??
估计往前或往后计算的方式和ByVal模式或ByRef模式有关吧。

-----------------------------------------------------------
另一点字元阵列利用指针进行字元重组后产生新的字符串,
透过strcpy到另一个字符串阵列中,最后倾印出来的结果,
等于没改。已经一步一步跟踪了,还特地一个字节一个字节的看,
也特地在结尾加'\0',结果输出档案还是等于没改。

这次跟踪也才知道在字元阵列结尾处加'\0'和加0和加10
各有不同的效用和目的,也对指针使用上有更多了解,
只是是蛮累人的。这部分属于C的,会另外再研究看看。

[ 本帖最后由 yz1025 于 2012-12-26 17:35 编辑 ]

不要投我
2012-12-26 17:27
快速回复:问个VB6 -> C (ByRef ByVal) 基础的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016831 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved