我创建了一个 C++ DLL,当从 VBA 调用时返回 SAFEARRAY*。
我的 VBA 函数:
Declare Function GetData_V Lib "xyz.dll" (ByVal path As String, ByVal id As String, ByRef inputArr() As String, ByRef output() As String) As Variant()
我的 C++ 实现:
SafeArrayLock(*outputArray);
for (LONG i = 0; i < countElements; i++)
{
CComBSTR bstr = CComBSTR(outputCustom[i]);
SafeArrayPutElement(*outputArray, &i, bstr);
}
SafeArrayUnlock(*outputArray);
delete [] outputCustom;
return *outputArray;
其中 outputCustom 定义为
outputCustom = new char*[nCount+1];
在 VBA 中,当我检查输出时,它显示字符串为:
1 0 . 9 4 4 9 d 0
2 . 8 3 4 6 d 0
0 . 0 1 1 8 d 0
0 . 6 2 9 9 d 0
0 . 6 2 9 9 d 0
0 . 6 2 9 9 d 0
2 5 . 0 d 0
0 . 0 7 6 4 d 0
1 0 . 9 4 4 9 d 0
2 . 8 3 4 6 d 0
0 . 0 1 1 8 d 0
我在 C++ 中调试了代码并检查了 *outputArray 的值,但一切都很好,但是当我在 VBA 中检查我的数组时,每个字符串的每个字符之间都有额外的空格。
最佳答案
与 VB6 一样,VBA 需要 Unicode(宽字符)字符串。
How to: Access DLLs in Excel -- Variant and String Arguments :
Excel works internally with wide-character Unicode strings. When a VBA user-defined function is declared as taking a String argument, Excel converts the supplied string to a byte-string in a locale-specific way. If you want your function to be passed a Unicode string, your VBA user-defined function should accept a Variant instead of a String argument. Your DLL function can then accept that Variant BSTR wide-character string from VBA.
您看到的空格是 16 位字符的零字节高字节。在将字符串传递给 CComBSTR
的构造函数之前,您需要使用 wchar_t
和/或转换为 widechar。您可以使用 MultiByteToWideChar
, mbstowcs
或 ATL and MFC String Conversion Macros去做。
了解 VBA 期望的一个好技巧是将此类对象从 VB 传递到您的 DLL 并在那里检查它。
关于c++ - 字符串的变体数组包含备用空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47512135/