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

VB.NET 調用 C++ DLL 結構體中字符數組傳遞漢字導致「數據區域太小」錯誤解決

     編輯:程式設計綜合問答

問題現象

C++ DLL 導出函數:
BOOL WINAPI InsUpdDel(LPSTR lpSqlStr, LPRTNINFO RtnInfo);
結構體:
typedef struct { long ErrCode; char ErrMsg[71]; } RTN_INFO;

VB.NET 調用時,lpSqlStr 傳漢字正常,但 RtnInfo.ErrMsg 返回漢字拋出 0x8007007A (數據區域太小)。

原因分析

  • LPSTR (輸入參數) 由調用方分配內存,長度由調用方控制,VB.NET 字符串按 ANSI 編碼封送傳遞,足夠大無問題。
  • LPRTNINFO (輸出參數) 結構體內存由調用方 (VB.NET) 預分配,封送拷貝器按結構體定義大小分配緩衝區。
    關鍵點: VB.NET Structure 默認 CharSet.Ansi 時,char[71] 按 1 字節/字符預留 71 字節。但 C++ 可能以 UTF-8 或雙字節字符集寫入,實際字節數超過 71 導致截斷/越界,封送器檢測到目標緩衝區不足拋出異常。

解決方案

方案一:C++ 端修改接口(推薦,不動 VB 代碼)

將結構體改為兩個獨立輸出參數:


// C++ 修改
DLLEXPORT BOOL WINAPI InsUpdDel(LPSTR lpSqlStr, long* pErrCode, LPSTR pErrMsg, int errMsgBufSize);
// 實現時檢查 errMsgBufSize,安全複製

VB.NET 端聲明:
Declare Function InsUpdDel Lib "xxx" (ByVal sql As String, ByRef errCode As Long, ByVal errMsg As StringBuilder, ByVal bufSize As Integer) As Boolean

方案二:VB.NET 端擴大緩衝區並指定編碼



Public Structure RTN_INFO
    Public ErrCode As Integer
     ' 擴大到 256 字節
    Public ErrMsg As String
End Structure

同時確保 C++ 寫入時不超過緩衝區長度(使用 strncpy_s 或 snprintf)。

建議

跨語言調用盡量避免結構體內嵌固定長度字符數組作為輸出,改用獨立字符串指針+長度參數,更安全可控。

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