VBA调用相同的C ++ dll会返回不同的结果

时间:2014-03-10 05:14:31

标签: c++ excel vba excel-vba dll

我有一个测试dll函数,它读取一个字符串并显示它:

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函数时,消息框仅显示字符串的第一个字符“a”。

我花了整整一个周末读BSTR等,仍然无法解决这个问题。这里发生了什么?

2 个答案:

答案 0 :(得分:2)

将导入的函数声明为private:

Private Declare Function test_internal Lib "test.dll" Alias "test" (ByVal text As String) As Long

并创建一个包装函数供Excel使用:

Public Function Test (ByVal text As String) As Long
  Test = test_internal(text)
End Functin

因为很明显,当VB(A)在调用Declare d API时使用当前系统代码页将字符串参数转换为ASCII时,Excel引擎不会。

另外,您还可以remove parentheses

答案 1 :(得分:1)

Excel将BSTR传递给您的C ++代码。每个字符用2个字节编码,第二个字符用0表示普通字符。这就解释了为什么你只看到第一个,因为MessageBoxA期望char * null终止字符串。使用

  

的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,使用一些ATL宏,或将原始Win32 API转换为WideCharToMultiByte(更棘手,更简单地使用ATL)