You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中unsigned char**赋值问题及VB调用异常排查

问题排查:DLL函数GetText与VB调用异常

问题背景

需编写替代旧版本的DLL,其中GetText函数必须遵循签名:

int GetText(unsigned char** outBuf, unsigned int* outLen);

测试时函数返回0(OK状态),但VB端弹出“Reading failed with status 0”对话框,且文本框无法显示内容。

相关代码

C++端GetText实现

int GetText(unsigned char** outBuf, unsigned int* outLen){  
*outBuf = NULL;
*outLen = 0;

//Create a char array from scratch, just to test...
unsigned char text[] = "Hello";

//outLen is the size of text
*outLen = sizeof(text);

//I allocate size to outBuf
*outBuf = new unsigned char[*outLen];

//I copy value of text into outBuf
memcpy(*outBuf, &text, *outLen);
    
return OK;
};

VB端调用代码

'lance la lecture
StatusInt = LectureText(NumText, textStr)
If StatusInt = 0 Then
    'traitement des sauts de ligne
    textStr= Replace(textStr, Chr(&HD) + Chr(&HA), Chr(&HA))
    textStr= Replace(textStr, Chr(&HA), Chr(&HD) + Chr(&HA))
    
    'copie dans la textbox
    Text1.Text = textStr
Else
    MsgBox "Lecture failed with err " & Str(StatusInt)
End If

VB端包装函数

Public Function LectureText(ByVal NumText, ByRef Text As String) As Long
Dim AddrText As Long
'Dim TextAs String
Dim LengthText As Long
Dim status As Long

'lecture du text
status = GetText(AddrText, LengthText)

'si lecture ok, copie et libère le buffer
If status = 0 And LengthText <> 0 Then
    'Alloue l'espace nécessaire pour le text
    Text = String(LengthText, vbNullChar)
    
    'copie du text
    CopyMemory ByVal Text, ByVal AddrText, LengthText
End If

'retourne status
LectureText= status
End Function

问题分析与修复方案

1. VB包装函数的参数传递错误

GetText的第一个参数是unsigned char**,需要接收分配好的缓冲区地址,因此在VB调用时必须以引用方式传递AddrText。原代码中调用GetText(AddrText, LengthText)时默认是传值(ByVal),导致AddrText无法被DLL修改,始终为初始值0,后续CopyMemory访问地址0会触发内存错误,最终导致内容无法显示且弹出错误提示。

修复: 修改VB包装函数中的GetText调用,给AddrText和LengthText都加上ByRef:

status = GetText(ByRef AddrText, ByRef LengthText)

同时要确保GetText在VB中的声明匹配:

Declare Function GetText Lib "YourDllName.dll" (ByRef outBuf As Long, ByRef outLen As Long) As Long

2. C++代码中memcpy的源地址错误

原代码中memcpy(*outBuf, &text, *outLen);使用&text作为源地址,虽然地址值与数组首地址相同,但&text是指向整个数组的指针(类型为unsigned char (*)[6]),语义上应直接使用数组首地址text。修正后避免潜在类型匹配问题:

memcpy(*outBuf, text, *outLen);

3. 内存释放问题(可选但重要)

C中用new分配的内存,VB无法直接用delete释放,会导致内存泄漏。如果旧版本DLL使用Windows堆分配函数,建议将C中的new替换为LocalAlloc,以便VB后续用LocalFree释放:

*outBuf = (unsigned char*)LocalAlloc(LPTR, *outLen);

然后在VB的CopyMemory之后添加释放代码:

LocalFree ByVal AddrText

总结

核心问题是VB调用GetText时未以引用方式传递缓冲区地址变量,导致DLL无法将分配的缓冲区地址返回给VB,后续内存访问出错。修正参数传递方式后,即可正常获取并显示文本内容。

内容的提问来源于stack exchange,提问作者momone50

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 13:30:54