首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 操作系统-> 注册表教程
vb vc混合编程疑难问题解_visualbasic教程
作者:网友供稿 点击:0
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 

  我们在编写VisualBasic应用程序的时候常常需要自己动手编写一些库函数或ActiveX控件,而这些函数或者控件常常采用VC 语言来写,因而也常为VB和VC两种语言之间不同参数类型、内存空间使用方法等问题为难,怎么做好呢?本文介绍了在VB和VC混合编程的情况下对这些问题的解决方法。

  一、自定义类型参数向DLL库函数的传递

  用VB,VC 进行混合编程时,通常需要在VB中调用VC 编写的DLL库函数,这时,一般都要遇到向库函数传递参数的问题。对于标准类型(如Double,Long等)参数,其传递比较简单,只要保证了VB中对库函数的声明和VC 中对库函数的定义在参数类型、次序和传递方式上的一致性,参数就不会被错误传递。但是,如果需要向库函数传递自定义类型的参数,情况就会变得复杂了。

  情况一:自定义类型的所有成员变量都是同一种类型(例如下面的Pens自定义类型,其成员都为Long型)。
TypePens
 RedPenNumAsLong
 GreenPenNumAsLong
 B1uePenNumAsLong
EndType
  这时,只要在VB和VC 中对该结构采用相同的定义,并充分注意到VB和VC 对某些数据类型(如32,位操作系统下,VC 中的int和VB中的Integer)存储上的差异,就不会发生参数传递错误。

  情况二:自定义类型中成员变量的类型不完全一致。这时,又要区分两种情况:

  情况(1)没有Double型成员变量。

  这时一般也不会出现参数的传递错误。

  情况(2)含有Double型成员变量。

  这时参数通常就会被误传。比如传递下面的Person类型的参数到VC 开发的DLL库函数,Double型成员Height的值就会在传递中丢失:
TypePerson
AgeAsLong
HeightAsDouble
EndType
  造成Height值丢失的原因是由于在VC 中存储Person型变量时,将自动在Long型成员Age和Double型成员Height之间插入若干字节的分隔空间,而VB则不会。所以,VC 中存储一个Person型变量需要的内存要多于12字节,而VB只需要12个。因此,从VB传入DLL库函数的Person型变量就不能被正确接收。

  解决这一问题的方法有多种,这里介绍一种比较简便和普适的,称之为“引入补位成员法”:在Person这种自定义类型中引入若干个内存补位成员,使得任一个Double型成员之前的所有成员占用的字节总数都是单个Double型变量所占字节数的整数倍(8的整数倍)。

  仍以Person类型为例,由于Age成员占用4字节内存,所以要在其后引入一个占用4字节的补位成员,不妨引入一个String型的成员Tempst:
TypePerson
 AgeAsLong
 TempstAsString*4
 HeightAsDouble
EndType
  于是,Double型成员Height之前的所有成员占用的内存总数变成了8个字节,是8的整数倍。此时,将DLL库函数中对Person的定义作同样的修改后,就可以正确接收从VB传来的Person型参数了。

  注意:引入补位成员时,不但要合理分配其占用的字节数,而且要正确安排其在结构体中的位置,二者缺一不可。上例中,若把补位成员放在Height之后,Doubl型变量Height之前的所有成员占用的字节总数仍然是4,不是8的整数倍。

  在自己编写DLL库函数时,往往会在函数接口处使用复杂的自定义结构。在VB中调用这种函数时,采用“引入补位成员法”适当修改结构体的定义,就可以有效地避免参数传递上的错误。

  二、使用在VC 中动态申请的内存

  混合语言编程时,有时需要在VB代码中使用通过VC 动态申请到的内存。这时,可以通过下述方法实现:

  1)VC 中申请动态内存的DLL库函数
char*APIENTRYCreateStringBuffer(longLength)
{
char*bufV;//假设需要申请用以存放字符申的动态内存
buf=(char*)::malloc(Length);
returnbuf;//返回字符串指针,其实就是一个long型数
}
  2)VB中接收动态内存指针的代码
......
DeclareFunctionCreateStringBufferLib"C:\DLLTest\Test.dll"_
(ByValLengthAsLong)AsLong
Long型变t接收动态内存指针
......
DimslBuffer&
atBuffer=CreateStringBuffer(20)
申请一块可存放20个字符的内存,得到指向该内存的指针
......
使用该动态内存
......
  注意:VB中使用完动态内存后,为了避免内存泄漏二要将其指针传回VC 进行内存释放工作。

  三、自定义类型参数向ActiveX控件的传递

  在编写VB程序时,如果使用的是标准ActiveX控件,那么一般不需要向控件传递自定义类型的参数,因为大多数控件的大多数属性都是标准类型(如Double,Long)的。但是,在混合语言编程中,当我们采用VC 中的ATL3.0模板(而不是VB)自行开发ActiveX控件时,往往希望能够向控件的某些属性或方法传递自定义类型的参数,以提高参数的传递效率。

  这里介绍一种向控件传递自定义类型参数的简便方法。假设要以VB为客户端开发一个ActiveX控件AX,它有一个Student属性,类型是自定义结构Person:
TypePerson
 AgeAsLong
 HeightAsDouble
EndType
  第一,正确编写Student属性的接口函数(以用ATL3.0模板开发AX为例)。我们将Student属性存取函数的接口参数类型写成一个long型的指针,而不再是BSTR。因为ActiveX内部的通信全部基于Unicode基础之上,所以,这样处理会避免由于字符集不匹配而造成的参数误传。相关的代码如下:

  1)AX.idl中对Student属性的定义
[propget,id(0),helpstring("propertyStudent")]HRESULT
Student([out,retval]long*pVal);
[propput,id(0),helpstring("propertyStudent")]HRESULT
Student([in]longnewVal);
  2)AX.h中对Student属性存取函数的定义
STDMETHOD(get_Student)(/*[out,retval]*/long*pVal);
STDMETHOD(put_Student)(/*[in]*/longnewVal);
  3)AXcpp中对Student属性存取函数的实现
STDMETHODIMPCAX::get_Student(long*pVal)
{
//TODD:Addyourimplementationcodehere
//得到存储Student属性的成员变t的指针,赋给*pVal
returnS_OK;
}
STDMETHODIMPCAX::put_Student(longnewVal)
{
//TODD:Addyourimplementationcodehere
//将存储Student属性的成员变址的指针指向newVal所指的内存空间,
//然后通过内存拷贝方式拷贝此空间存放的Student的属性值
returnS_OK;
}
  第二,正确编写VB向AX的Student属性动态赋值的代码。在VB中,先声明一个Person型变量,给该变量赋值后,获取该变量的内存地址并赋给Student属性即可。代码如下:
......
DimStudentPropAsPerson
DimStudentAddrAsLong
StudentProp.Age=23
StudentProp.Heigth=1.78
得到StudentProp变量的内存地址(方法从略),赋给StudentAddr
AX1.Student=StudentAddr
......
  借助指针完成自定义类型参数向ActiveX控件的传递所依据的是以下事实:不论控件是.dll还是.ocx,它都是与其客户同在一个进程内的服务器。所以,只要AX被编译成.dll或.ocx,指针的传递就是安全可靠的。

  四、中英文混合型字符串输出长度的确定

  中英文混合型字符串输出长度的确定问题在VB编程中经常遇到,而且可以通过VB,VC 混合编程有效解决,所以在此一并给出。

  VB编程中,经常需要得到某个字符串在实际输出时所需要的长度。这时,我们通常会考虑Len()和LenB()这两个函数。

  我们知道,Len()返回的是字符串中字符的个数,对于不含中文字符的字符串,其返回值通常就等于该字符串的输出长度;LenB()返回的则是按照双字节字符集(DBCS)计算出的字符串所占用的字节数,对于纯中文字符组成的字符串,其返回值通常也等于该字符串的输出长度。但是,当字符串中既有中文又有英文(这里将数字等视为英文)字符时,二者的返回值都不等于该字符串的输出长度。比如:“A中国人”这个字符串,用Len()函数时将返回4;LenB()则返回8;而实际输出时(比如向某记录文件输出该字符串),它将占用7个印刷符(每个英文字符占1个,每个中文字符占2个)。

  为了计算中英文混合型字符串的输出长度,我们可以用VC 编写一个完成此计算的DLL库函数,在VB中直接调用该函数即可。该VC 函数和VB中的调用代码如下:

  1)VC 6.0中的DLL函数
longAPIENTRYSizeof_vbString(char*at)
{
return(long)(::atrlen(st));
//::atrlen()返回int值,但在32位操作系统下,
//VC 中的int类型与VB中Long类型的范围是相当的
}
  2)VB6.0中对Sizeof_vbString()的声明和调用
......
DeclareFunctionSizeof_vbStringLib"C:\DLLTest.dll"_
(ByValstAsString)AsLong
......
......
DimstLen&
stLen=Sizeof_vbString("A中国人")
stLen=7
......
  应该指出:上述方法同样可以计算纯英文或纯中文字符串的输入长度。

->


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·更改internet explorer的图标
·C#中的类型转换-.NET教程,C#语言
·找回flash的序列号sn
·更改ie的图标
·如何让你的VB6 IDE支持鼠标滚轮(过程)-.NET教程,VB.Net语言
·正则表达式Replace-.NET教程,Asp.Net开发
·Windows 2003下不注册组件用ASP发邮件-ASP教程,邮件相关
·防止ie被恶意修改的初级技巧
·asp.net实现分组全选部分复选框-ASP教程,ASP应用
·清理ie网址列表
最新文章
·seo新手教程:title的写法_seo网站优化
·从注册表下手 切断一切黑客入侵的路径_注册表教程
·用flash 8 as代码写摄像头拍照功能_flash教程
·小站长赚钱思路:ip不到1000,一个月赚940元_网赚技巧
·陈艺光:网络游戏平台与游戏网站实现共赢_站长访谈
·留住访客 如何最优化设计网站的首页?(2)_站长心得
·为什么在google上搜不到我的网页?_google推广
·google的秘密 搜索引擎利用软件的魔力加快奔跑_google推广
·域名与网站排名_站长心得
·怎样避免被搜索引擎视为作弊_站长心得
相关主题
西部数码虚拟主机

友情链接
CNNIC 西部数码
万网 自助建站
虚拟主机 asp空间
域名注册 域名
域名申请 主页空间
论坛空间 网站空间
国际域名 虚拟空间
空间租用 DDOS防火墙
成都主机托管 四川主机托管
主机租用 服务器租用
网站目录 自助建站
虚拟主机 网址大全
软件下载
自助链接
虚拟主机资讯 特价虚拟主机
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
发表评论 打印  刷新     关闭