Strings von VBA nach C ++ DLL übergeben

Ich bin wirklich verwirrt, wenn es darum geht, Zeichenfolgen von VBA an C ++ zu übergeben. Hier ist der VBA-Code:

Private Declare Sub passBSTRVal Lib "foo.dll" (ByVal s As String)
Private Declare Sub passBSTRRef Lib "foo.dll" (ByRef s As String)
Private Declare Sub passByNarrowVal Lib "foo.dll" (ByVal s As String)
Private Declare Sub passByNarrowRef Lib "foo.dll" (ByRef s As String)
Private Declare Sub passByWideVal Lib "foo.dll" (ByVal s As String)
Private Declare Sub passByWideRef Lib "foo.dll" (ByRef s As String)

Sub foobar()
    Dim s As String, str As String
    str = "Hello There, World!"

    s = str
    Call passByBSTRVal(s)
    s = str
    Call passByBSTRRef(s)
    s = str
    Call passByNarrowVal(s)
    s = str
    Call passByNarrowRef(s)
    s = str
    Call passByWideVal(s)
    s = str
    Call passByWideRef(s)
End Sub

Und der C ++ - DLL-Code:

void __stdcall passByBSTRVal( BSTR s )
{
    MessageBox(NULL, s, L"Pass BSTR by value", MB_OK | MB_ICONINFORMATION);
}

void __stdcall passByBSTRRef( BSTR *s )
{
    MessageBox(NULL, *s, L"Pass BSTR by ref", MB_OK | MB_ICONINFORMATION);
}

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

void __stdcall passByNarrowRef( LPCSTR* s )
{
    USES_CONVERSION;
    MessageBox(NULL, A2W(*s), L"Pass by Narrow Ref", MB_OK | MB_ICONINFORMATION);
}

void __stdcall passByWideVal( LPCWSTR s )
{
    MessageBox(NULL, s, L"Pass by Wide Val", MB_OK | MB_ICONINFORMATION);
}

void __stdcall passByWideRef( LPCWSTR* s )
{
    MessageBox(NULL, *s, L"Pass by Wide Ref", MB_OK | MB_ICONINFORMATION);
}

Meine Erwartung war, dass die ersten beiden Aufrufe von passByBSTRVal und passByBSTRRef funktionieren würden. Warum? Weil VBA-Zeichenfolgen COM-BSTR-Objekte sind. Beim Durchlaufen des C ++ - Codes war der Wert von s für beide Funktionen jedoch Garbage (eine Reihe von Kanji). Darüber hinaus war das angezeigte Meldungsfeld (dasselbe). Ich bin wirklich überrascht, dass die ersten beiden Funktionen nicht funktioniert haben.

Meine nächste Erwartung war, dass die beiden zweiten Aufrufe von passByNarrowVal und passByNarrowRef nicht funktionieren, da ein BSTR als "typedef OLECHAR * BSTR" definiert ist und ein OLECHAR ein breiter Zeichentyp ist, während LPCSTR ein schmaler Zeichentyp ist. Entgegen meiner Erwartung funktionierten diese beiden Funktionen jedoch tatsächlich. Als ich durch den C ++ - Code schritt, war der Parameter s genau das, was ich erwartet hatte. Meine Erwartung war wieder falsch.

Zuletzt erwartete ich für die letzten 2 Funktionen (übergeben von wide val und ref), dass sie funktionieren würden, da ein OLECHAR eine Zeichenfolge mit breiten Zeichen ist, sodass ein LPCWSTR in der Lage sein sollte, auf ein BSTR zu verweisen. Aber wie in Fall 1 (ich denke, diese beiden Fälle sind identisch) war meine Erwartung falsch. Der Parameter s bestand aus Müllzeichen (und die MessageBox zeigte dieselben Müllzeichen an.)

Warum war meine Intuition völlig falsch? Kann mir bitte jemand erklären, was ich hier nicht verstehe?

Antworten auf die Frage(8)

Ihre Antwort auf die Frage