【发布时间】:2021-08-31 16:00:27
【问题描述】:
我需要使用 DLL 从老式 INI 文件中读取条目,并在进行一些操作后将它们导出为 VBA 代码。
函数的 c++ 代码如下所示:
BSTR __stdcall GetSectionEntry(LPCSTR sSection, LPCSTR sEntry)
{
LPCTSTR gszINIfilename = "C:\\test\\test.ini";
TCHAR localStr[64];
GetFileAttributes(gszINIfilename);
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(gszINIfilename) && GetLastError() == ERROR_FILE_NOT_FOUND) {
bstr_t bstrt = "";
return bstrt;
} else {
GetPrivateProfileStringA(sSection, sEntry, "", localStr, sizeof(localStr), gszINIfilename);
//_bstr_t bstrt(localStr);
CComBSTR bstrt(localStr);
return bstrt;
}
}
VBA(Word 2016):
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 = " & StrConv(GetSectionEntry("Name", CStr(i)), vbFromUnicode))
Next i
最后结束 INI 文件:
[Name]
0=123456789012345678901234567
1=1234567890123456789012345678
2=1234567890123456789012345678901234567890123456789012345678901
3=12345678901234567890123456789012345678901234567890123456789012
我使用 VS2019 编译 DLL,并将“字符集”设置为“未设置”或“使用多字节字符集”。
在 VS 中调试显示字符串的格式正确(例如,对于 1,它是 L"1234567890123456789012345678")。我用不同大小的 localStr (64..1024) 对其进行了测试。我尝试了 bstr_t 和 CComBSTR 等等。在所有情况下,VBA 中的 print.debug 显示以下结果:
Name = 123456789012345678901234567
Name = ?????????????? ????????????
Name = ??????????????????????????????1 ?? ??????????????yu ? rg|A ?
Name = 12345678901234567890123456789012345678901234567890123456789012
任何长于 27 且短于 62 个字符的字符串都未正确编码。当我在没有 StrConv(string, vbFromUnicode) 的情况下检查它们时,它们甚至丢失了所有空字符。 因此,它们被编码为一些亚洲字符:
对于长度为 13--14 个字符的字符串也是如此:
我很确定我在做一些微不足道和愚蠢的事情,但我从来不需要为 Windows 编写任何 C/C++。如果有人能指出我的错误并纠正我,我将不胜感激。
【问题讨论】:
-
你真的必须通过这个 DLL 而不是直接从 INI 读取吗?
-
@yves-daoust :是的,我愿意。我不会问。 :)