【问题标题】:C++ dll for VBA - problem with reading/encoding stringsVBA 的 C++ dll - 读取/编码字符串的问题
【发布时间】: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_tCComBSTR 等等。在所有情况下,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 :是的,我愿意。我不会问。 :)

标签: c++ vba dll


【解决方案1】:
    CComBSTR bstrt(localStr);
    return bstrt;

此返回语句将 CComBSTR 转换为 BSTR,并将其返回,然后销毁 CComBSTR,因为它不再在范围内。当 CComBSTR 对象被销毁时the string is freed.

试试return bstrt.Detach(); which detaches the string from the CComBSTR object 这样它就不会被析构函数释放。

返回后,字符串“属于”VBA,VBA 负责释放它,我假设它会自动完成。

【讨论】:

  • 谢谢,速度很快...我已经重新编译,看起来一切正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-08
相关资源
最近更新 更多