VBA call same C++ dll return different results

笑着哭i 提交于 2020-01-15 02:39:05

问题


I have a test dll function that reads a string and display it:

int _stdcall test(LPSTR myString) {
MessageBoxA(NULL, (LPCSTR)myString, "test", MB_OK);
return 0;}

The excel VBA declaration is

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

There is a sub that calls the function. It reads an excel cell with value as "abcde" and is able to display a correct result. The sub code is:

sub testCode()
    test (cells(1,1).value)
end sub

However when call the dll function using excel formula =test(A1), the message box only display the first char "a" of the string.

I had spent entire weekend reading BSTR, etc, still not be able to solve this. What is going on here?


回答1:


Declare your imported function as private:

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

and create a wrapper function for Excel to use:

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

Because apparently, while VB(A) converts string arguments to ASCII using the current system codepage when calling to Declared APIs, the Excel engine does not.

On a side note, you also might want to remove parentheses.




回答2:


Excel pass a BSTR to your C++ code. Each character is coded with 2 bytes, the second one being 0 for common characters. That explains why you see only the first one, as MessageBoxA expects char* null terminated strings. Use

MessageBoxW

Try with that code

int _stdcall test( const wchar_t * pString ) {
   MessageBoxW( NULL, pString, L"test", MB_OK ); // note the L prefix for literral
   return 0;
}

Alternatively, you could translate the BSTR pointer to a char* one, using some ATL macros, or raw Win32 APIs as WideCharToMultiByte (more tricky, mush simpler to use ATL)



来源:https://stackoverflow.com/questions/22292531/vba-call-same-c-dll-return-different-results

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!