首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

VB 舷 VC 混合編程疑難雜症全解析:參數傳遞、記憶體管理、ActiveX 介面與字串長度計算

     編輯:更多程式設計知識

VB (VB6) 與 VC++ (Visual C++) 混合開發曾是 Windows 桌面應用主流模式。雖技術棧老舊,許多存續系統仍在運維。本文系統整理四大核心痛點:自訂類型跨語言傳遞對齊、VC 動態記憶體跨邊界使用、ActiveX 介面指標傳遞、中英混排字串長度計算,提供經實戰驗證的解決方案與程式碼範本。

一、自訂類型 (Struct/UDT) 向 DLL 傳遞:記憶體對齊陷阱

情況 1:成員型別相同 (如全 Long)

VB 與 VC 結構定義對應即可,注意 32 位環境 Long (VB) = long (VC) = 4 bytes。

情況 2:成員型別混合且含 Double


' VB 端
Type Person
    Age As Long        ' 4 bytes
    Height As Double   ' 8 bytes
End Type

VC 結構會在 Age 後插入 4 bytes padding 使 Height 8-byte 對齊,導致總大小 16 bytes;VB 無 padding 僅 12 bytes,傳遞時位移錯位。

解決方案:引入補位成員法


' VB 端補上 4 bytes 字串
Type Person
    Age As Long
    Padding As String * 4   ' 佔位 4 bytes
    Height As Double
End Type

// VC 端對應
struct Person {
    long Age;
    char Padding[4];   // 或 double dummy; 但 char[4] 更明確
    double Height;
};

原則:確保每個 Double 前的成員總大小為 8 的倍數。補位成員位置必須緊鄰 Double 之前。

二、VC 動態記憶體跨越 DLL 邊界給 VB 使用

VC 端:匯出配置函數


char* APIENTRY CreateStringBuffer(long Length) {
    char* buf = (char*)malloc(Length);
    return buf;  // 實際回傳指標值 (32 位下相當於 long)
}

VB 端:以 Long 接收指標


Declare Function CreateStringBuffer Lib "Test.dll" (ByVal Length As Long) As Long

Dim ptr As Long
ptr = CreateStringBuffer(20)  ' 取得指標
' ... 透過 CopyMemory / RtlMoveMemory 讀寫該記憶體 ...
' 用完後必須呼叫 VC 匯出的 Free 函數歸還,否則記憶體洩漏

鐵律:誰配置誰釋放。VB 使用完畢必須呼叫 VC 提供的 FreeBuffer(ptr)。

三、自訂類型向 ActiveX 控件傳遞:指標法避開 Unicode 轉換

ATL 開發 ActiveX 時,介面定義 (IDL) 若用 BSTR 會觸發 ANSI/Unicode 轉換,導致二進位結構損壞。解法:介面以 long (指標) 傳遞:


// IDL
[propget] HRESULT Student([out, retval] long* pVal);
[propput] HRESULT Student([in] long newVal);

// VB 客戶端
Dim StudentProp As Person
Dim StudentAddr As Long
StudentProp.Age = 23
StudentProp.Height = 1.78
StudentAddr = VarPtr(StudentProp)  ' 取得變數位址 (需 VarPtr 函數)
AX1.Student = StudentAddr          ' 傳指標

前提:ActiveX 為 In-process (DLL/OCX),同一進程空間指標有效。

四、中英混排字串列印長度計算:VC 運行期庫函數

VB Len() 算字元數,LenB() 算位元組數,混合字串兩者皆不準 (如 "A中國人" 顯示寬度 7)。

VC DLL 函數


long APIENTRY Sizeof_vbString(char* str) {
    return (long)strlen(str);  // 以位元組計算,剛好等於顯示寬度 (單位:半形字元寬度)
}

VB 宣告與呼叫


Declare Function Sizeof_vbString Lib "Test.dll" (ByVal str As String) As Long

Dim len As Long
len = Sizeof_vbString("A中國人")  ' 回傳 7

同樣適用純中文/純英文字串。

總結檢查清單

  • [ ] 結構體成員對齊:Double 前補位至 8 的倍數。
  • [ ] 動態記憶體:VC 配置/釋放成對,VB 僅持有指標。
  • [ ] ActiveX 介面:用 long 傳指標,避開 BSTR 轉換。
  • [ ] 字串寬度:委託 VC strlen 計算位元組長度。

遵循上述模式,可消除 VB/VC 混合編程 90% 以上的疑難雜症。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved