string的变体数组包含替代空格

我创build了一个C ++ DLL,当从VBA调用时返回SAFEARRAY *。

我的VBAfunction:

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中,当我检查输出时显示string为:

 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 

我debugging了代码并检查了C ++中的* outputArray的值,但是一切都很好,但是当我在VBA中检查数组时,它在每个string的每个字符之间都有额外的空格。

与VB6一样,VBA期望Unicode(宽字符)string。

如何:在Excel中访问DLL – 变体和string参数 :

Excel在内部使用宽字符的Unicodestring。 当一个VBA用户定义的函数被声明为接受一个String参数时,Excel将提供的string转换为一个特定于语言环境的字节string。 如果你想让你的函数传递一个Unicodestring,你的VBA用户定义的函数应该接受一个Variant而不是一个String参数。 然后您的DLL函数可以接受来自VBA的Variant BSTR宽字符string。

您看到的空格是16位字符的零字节高字节。 在将string传递给CComBSTR的构造函数之前,您需要使用wchar_t和/或转换为widechar。 您可以使用MultiByteToWideCharmbstowcs或ATL和MFCstring转换macros来执行此操作。

一个很好的提示,看看VBA所期望的是将这样的对象从VB传递到你的DLL并在那里检查它。

埃里克的BSTR语义完全指南也是一个有趣的阅读。