我有一个测试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等,仍然无法解决这个问题。这里发生了什么?
答案 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)