I've written a c++ function in a DLL which exports a string to a VBA program:
BSTR _stdcall myFunc()
{
CRegKey Key;
CString sValue;
BSTR Str;
LONG nA = Key.Open(HKEY_LOCAL_MACHINE, _T("[group path goes here]"), KEY_READ);
ULONG nValueLength = 0;
LONG nB = Key.QueryStringValue(_T("[key I want to read goes here]"), NULL, &nValueLength);
if (nValueLength > 0)
{
LONG nC = Key.QueryStringValue(_T("[key I want to read goes here]"), sValue.GetBufferSetLength(nValueLength - 1), &nValueLength);
}
Str = _bstr_t(sValue.AllocSysString(), false);
return Str;
Now Str
is something like a version number: let's say "4.10.122".
If I call the function from VBA, I receive instead "4 . 1 0 . 1 2 2", where the "spaces" between each characters are NULL
(in VBA they are Chr(0)
).
I don't like the idea of having to use the Replace
function in my VBA code, so is there any way I can include that step in my c++ code?
EDIT: below the code I'm using to call the function in VBA:
Private Declare Function myFunc Lib "[Path of my DLL here]" () As String
Sub Return_string()
Dim a As String
a = myFunc()
End Sub
Far from being able to help you with this specific need but curious about the subject, if i were to come up with a solution i would start from this answer https://stackoverflow.com/a/43423527/781933
According to the above mentioned @SimonMourier detailed answer, and further readings, you should consider string content encodings. The context of the DLL - VBA marshalling is to be considered and depends also on VBA function declaration (stated by @HansPassant).
From this MSDN documentation:
So if you use:
Private Declare Function myFunc Lib "[Path of my DLL here]" () As String
conversion from UNICODE to ANSI is needed via StrConv
Dim str As String
str = StrConv(myFunc(), vbFromUnicode)
Otherwise you should get rid of StrConv
but using DLL exported BSTR
with this declaration:
Private Declare Function myFunc Lib "[Path of my DLL here]" () As Variant