VBA调用相同的C ++ DLL会返回不同的结果
我有一个testingDLL函数读取一个string,并显示它:
int _stdcall test(LPSTR myString) { MessageBoxA(NULL, (LPCSTR)myString, "test", MB_OK); return 0;}
excel的VBA声明是
Declare Function test Lib "test.dll" (ByVal text As String) As Long
有一个子调用该函数。 它读取一个值为“abcde”的excel单元格,并能够显示正确的结果。 子代码是:
sub testCode() test (cells(1,1).value) end sub
但是,使用Excel公式=test(A1)
调用dll函数时,消息框只显示string的第一个字符“a”。
我整个周末都在读BSTR等,还是无法解决这个问题。 这里发生了什么?
将导入的函数声明为private:
Private Declare Function test_internal Lib "test.dll" Alias "test" (ByVal text As String) As Long
并为Excel创build一个包装函数来使用:
Public Function Test (ByVal text As String) As Long Test = test_internal(text) End Functin
因为显然,当调用Declare
d API时,VB(A)使用当前系统代码页将string参数转换为ASCII,但Excel引擎不会。
在旁注中,您也可能要删除括号 。
Excel将BSTR
传递给您的C ++代码。 每个字符用2个字节编码,第二个字符为0。 这就解释了为什么你只看到第一个,因为MessageBoxA
需要char * null结尾的string。 使用
MessageBox W
试试这个代码
int _stdcall test( const wchar_t * pString ) { MessageBoxW( NULL, pString, L"test", MB_OK ); // note the L prefix for literral return 0; }
或者,您可以将BSTR指针转换为char * one,使用一些ATLmacros或原始的Win32 API作为WideCharToMultiByte (更棘手,使用ATL更简单)