0

I expected to be be able to pass a VBA string to a C++ DLL function.

Here is the C++ code (compiled in Visual Studio Community 2022 as a x64 Debug):

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <Windows.h>

extern "C" {

    __declspec(dllexport) void ShowMessage(LPSTR message) {

        MessageBoxA(NULL, message, "DLL Message", MB_OK);

    }

}

And the Excel VBA code (Excel Version 2307 Build 16.0.16626.20170, 64-bit):

'Test function
Declare PtrSafe Function ShowMessage _
    Lib "MyFunTest.dll" (ByVal message As String)


Function VBShowName()

    Dim str_message As String
    str_message = "Hello World"
    ShowMessage (str_message)
     
    VBShowName = str_message
    
End Function

When I compile the DLL and run in debug, Visual Studio shows that message in C++ has a value of "" (as if I had not initialized the str_message variable in VBA) as soon as I enter the function. I see the VBA function returns the value of Hello World so I think I am storing the string correctly in VBA.

I need help understanding how to pass strings from Excel VBA to a C++ DLL (I'm upgrading old C++ code from 2010 that used to work with 32-bit Excel).

I've read through a few articles (Passing Strings to a DLL Procedure,Access DLLs in Excel, Pass String from VBA to C DLL to Modify as a Parameter and Return, Passing strings from VBA to C++ DLL) to troubleshoot the problem, but have not been able to pass the string.

VBA passes "" to the C++ DLL regardless of what I've tried.

I also tried using the BSTR type for the input to the DLL function, but got the the same "" values.

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <Windows.h>
#include <oleauto.h>


extern "C" {

    __declspec(dllexport) void ShowMessage(BSTR message) {

        MessageBoxW(NULL, message, L"DLL Message", MB_OK);

    }

}

I tried LCSTR as well, but didn't get the string in C++. Instead in showed '\f'. Here's the C++ code:

    extern "C"  __declspec(dllexport) void __stdcall passByNarrowVal(LPCSTR s)
    {
        USES_CONVERSION;
        MessageBox(NULL, A2W(s), L"Pass by Narrow Val", MB_OK | MB_ICONINFORMATION);
    }

Here's the VBA Code:

Declare PtrSafe Function passByNarrowVal _
    Lib "MyFunTest.dll" (ByVal s As String)

Dim tline As String
tline = "Hello World"
passByNarrowVal (tline)
  • Are you sure VBA is passing in a ascii string and not a wide character string? (LPWSTR/MessageBoxW) ? – Pepijn Kramer Aug 31 '23 at 05:15
  • Thank you. I believe VBA passes in a BSTR object. I've also tried declaring the input argument to the DLL function as BSTR, but got the same results. – Brian Howard Aug 31 '23 at 05:19
  • It was just an idea I had, soooo long ago I used VB (and even then I used COM as interop not direct DLL access from VBA to C++) – Pepijn Kramer Aug 31 '23 at 05:28
  • @BrianHoward So usage of `LongPtr` at the [link you posted](https://stackoverflow.com/questions/39404028/passing-strings-from-vba-to-c-dll) did not work? – PaulMcKenzie Aug 31 '23 at 06:25
  • @PaulMcKenzie I did try that implementation. It didn't pass the string, it had '\f' (12) looking like a random number. I'll add my code snippets to the main body so you can see it. – Brian Howard Aug 31 '23 at 13:11
  • @BrianHoward I don't use VBA, but I don't see you using what the linked answer is using, namely `StrPtr` in the VBA code. I am looking at the answer that has been upvoted 10 times. You also could have tested directly without having to write a DLL by trying to simply call the Windows API `MessageBox` function from VBA. If that can't be accomplished, writing a DLL isn't going to work either. – PaulMcKenzie Aug 31 '23 at 13:17
  • That's a `Sub`, not a Function. The function return type is not declared, so VBA assumes Object. Which requires space on the stack, thus throwing off the parameter address. – Hans Passant Aug 31 '23 at 13:51
  • @HansPassant That was it! Stupid mistake and a nice catch on your part. Thank you very much! I'm new to stack overflow so I'm not sure exactly how to close this out. Can this comment be converted to an answer so I can close this out? – Brian Howard Sep 01 '23 at 14:59

0 Answers0