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。 您可以使用MultiByteToWideChar
, mbstowcs
或ATL和MFCstring转换macros来执行此操作。
一个很好的提示,看看VBA所期望的是将这样的对象从VB传递到你的DLL并在那里检查它。
埃里克的BSTR语义完全指南也是一个有趣的阅读。