亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

VB VC混合編程疑難問題解

2019-11-18 17:55:21
字體:
來源:轉載
供稿:網友

  我們在編寫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屬性的定義
[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屬性即可。代碼如下:
......
DimStudentProp
asperson
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
......
  應該指出:上述方法同樣可以計算純英文或純中文字符串的輸入長度。

->


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
秋霞成人午夜鲁丝一区二区三区| 亚洲肉体裸体xxxx137| xx视频.9999.com| 精品国产一区二区三区四区在线观看| 日韩国产欧美精品在线| 国产噜噜噜噜噜久久久久久久久| 91免费综合在线| 日韩高清免费在线| 亚洲欧美一区二区三区在线| 欧美黄色三级网站| 日韩精品亚洲视频| 国产精品三级美女白浆呻吟| 久久视频国产精品免费视频在线| 久久久久久国产三级电影| 亚洲成人中文字幕| 国产午夜精品理论片a级探花| www.亚洲成人| 国内成人精品视频| 国产99久久精品一区二区| 国产99在线|中文| 日韩免费不卡av| 日韩一级裸体免费视频| 欧美日本高清视频| 亚洲男人的天堂网站| 91免费版网站入口| 精品国产91久久久久久| 美女av一区二区| 亚洲国产精品推荐| 国产精品xxxxx| 国模精品系列视频| 国产精品香蕉av| 久久精品色欧美aⅴ一区二区| 亚洲精品国产精品国自产在线| 国产福利成人在线| 亚洲精品美女网站| 成人av在线天堂| 中文字幕亚洲在线| 久久久久久久久久久免费精品| 久久精品99久久香蕉国产色戒| 久久久国产精品x99av| 午夜精品久久久久久99热软件| 欧美综合国产精品久久丁香| 成人免费视频网址| 亚洲成人久久电影| 一道本无吗dⅴd在线播放一区| 亚洲人在线视频| 国产成人黄色av| 国产精品久久久久免费a∨大胸| 精品久久久久久久久久ntr影视| 中文字幕国产精品| 91久久精品在线| 精品国产拍在线观看| 日韩经典中文字幕| 欧美成人h版在线观看| 久久久久久中文| 国产区精品在线观看| 日韩在线欧美在线| 日韩精品中文字幕在线播放| 日韩**中文字幕毛片| 国产精品伦子伦免费视频| 国产精品视频26uuu| 亚洲最大福利网站| 日韩欧美一区视频| 久久精品亚洲精品| 成人午夜激情网| www.欧美三级电影.com| 91极品视频在线| 97在线看免费观看视频在线观看| 欧美极品少妇xxxxⅹ裸体艺术| 欧美日韩福利在线观看| 91精品视频在线| 国产精品电影在线观看| 国产精品视频99| 91亚洲精华国产精华| 欧美一区二区三区四区在线| 久久99热精品这里久久精品| 亚洲高清在线观看| 欧美高清在线视频观看不卡| 亚洲小视频在线观看| 日韩女优人人人人射在线视频| 欧美极品美女视频网站在线观看免费| 亚洲精品不卡在线| 国产精品高清在线观看| 日本精品性网站在线观看| 国产精品美女久久久免费| 国产亚洲精品久久久久久牛牛| 久久视频精品在线| 中文字幕久久精品| 91av在线精品| 欧美高清视频一区二区| 成人黄色免费片| 日韩小视频在线观看| 亚洲美女精品久久| 亚洲男女性事视频| 国产精品va在线播放我和闺蜜| 国产主播精品在线| 精品国产鲁一鲁一区二区张丽| 国产精品黄色av| 国产女人18毛片水18精品| 97在线日本国产| 国产狼人综合免费视频| 欧美日韩视频在线| 少妇高潮 亚洲精品| 久久国产加勒比精品无码| 日韩成人激情影院| 亚洲专区在线视频| 久久久影视精品| 美女扒开尿口让男人操亚洲视频网站| 91wwwcom在线观看| 91免费精品国偷自产在线| 国产主播在线一区| 人人澡人人澡人人看欧美| 精品国内自产拍在线观看| 亚洲人在线观看| 国产精品久久久久99| 国产精品亚洲欧美导航| 日韩久久精品电影| 欧美香蕉大胸在线视频观看| 国产一区二区三区直播精品电影| 国产精品成人一区二区| 亚洲人成在线观| 国产精品久久久久77777| 91精品国产自产91精品| 三级精品视频久久久久| 久热爱精品视频线路一| 欧美激情精品久久久久久| 亚洲欧洲偷拍精品| 欧美一区二区大胆人体摄影专业网站| 97在线观看免费高清| 一区二区成人av| 亚洲免费视频一区二区| 精品亚洲一区二区三区四区五区| 欧洲永久精品大片ww免费漫画| 久久久999成人| 亚洲精品视频在线播放| 欧美与欧洲交xxxx免费观看| 精品动漫一区二区| www.亚洲人.com| 亚洲电影在线看| 久久综合免费视频影院| 久久久免费在线观看| 亚洲xxxxx电影| 亚洲精品videossex少妇| 狠狠躁夜夜躁人人爽天天天天97| 日韩欧美在线视频| 欧洲日韩成人av| 狠狠躁夜夜躁久久躁别揉| 亚洲精品电影网在线观看| 成人欧美一区二区三区黑人| 亚洲精品一区二三区不卡| 一区二区三区亚洲| 午夜伦理精品一区| 久久这里只有精品视频首页| 精品高清一区二区三区| 色噜噜久久综合伊人一本| 亚洲国产美女精品久久久久∴| 久久久免费观看| 97免费在线视频| 亚洲va国产va天堂va久久| 中文字幕亚洲综合久久筱田步美| 亚洲欧美日韩成人| 亚洲国产精久久久久久久| 91精品国产高清久久久久久| 91日韩在线视频|