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

供VBA调用的C++ DLL读取INI文件字符串编码异常问题

错误原因

  • 字符编码匹配错误:VBA原生使用UTF-16(Unicode)编码字符串,调用C++ DLL时,输入String参数会自动转换为ANSI编码传入,但返回BSTR类型时VBA会默认按UTF-16解析,你的代码中存在多次冗余编码转换,导致字符乱码
  • 缓冲区参数不规范:GetPrivateProfileStringA要求传入的缓冲区大小参数是字符数,你的代码传了sizeof(localStr),虽然多字节字符集下char的大小是1字节暂时没问题,但属于不规范写法,切换字符集时很容易出错
  • 冗余的VBA编码转换:你调用StrConv(..., vbFromUnicode)属于多余操作,会把已经是UTF-16的字符串强制按单字节解析再转存为UTF-16,直接导致中长字符串乱码

修正方案

第一步:修改C++ DLL代码

统一使用Unicode接口,避免字符集不匹配问题:

BSTR __stdcall GetSectionEntry(LPCWSTR sSection, LPCWSTR sEntry)
{
    // 文件名直接用宽字符定义,避免转义错误注意是双反斜杠
    LPCWSTR gszINIfilename = L"C:\\test\\test.ini";
    WCHAR localStr[1024] = {0}; // 统一用宽字符缓冲区,大小可按需调整
    
    if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(gszINIfilename) && GetLastError() == ERROR_FILE_NOT_FOUND) {
        return SysAllocString(L"");
    } else {
        // 调用Unicode版本的INI读取API,缓冲区大小传数组元素个数
        GetPrivateProfileStringW(sSection, sEntry, L"", localStr, _countof(localStr), gszINIfilename);
        return SysAllocString(localStr);
    }
}

VS编译时字符集建议改为「使用Unicode字符集」,避免宏定义不匹配

第二步:修改VBA调用代码

删除冗余的编码转换,直接用简化版声明即可:

Declare PtrSafe Function GetSectionEntry Lib "test.dll" (ByVal sSection As String, ByVal sEntry As String) As String

For i = 0 To 5
    ' 不需要任何编码转换,直接输出即可
    Debug.Print "Name = " & GetSectionEntry("Name", CStr(i))
Next i

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 21:42:00