Wie konvertiere ich char * in BSTR?

Lesezeit: 4 Minuten

Wie kann ich ein Zeichen * von C DLL an VB übergeben

Hier ist Beispielcode:

void Cfunc(char *buffer,int len)
{
  BSTR buf_bstr = SysAllocString((BSTR)buffer);
  VBptr.VBfunc(buf_bstr,len);
}

Diese Funktion funktioniert nicht, tatsächlich werden andere Werte als der tatsächliche Wert an die VB gesendet.

Könnte jemand bitte eine Lösung vorschlagen?

  • Können Sie ein Beispiel für eine Originalzeichenfolge im Vergleich zum falschen Wert geben, der gesendet wird?

    – Aidan Ryan

    3. März 2009 um 11:51 Uhr

  • Ihr (ursprüngliches) Problem scheint die Zeichenbreite zu sein. Ein BSTR besteht immer aus Breitzeichen (COM ist alles Unicode). Ein Cast wird die Zeichen nicht automatisch erweitern, sondern die Bytes als wchar_t* interpretieren.

    – Richard

    3. März 2009 um 11:55 Uhr

  • Dieser Pseudocode weist ein Speicherleck auf. Sie rufen SysAllocString() auf, geben die Zeichenfolge aber nicht frei, wenn Sie sie nicht mehr benötigen.

    – scharfer Zahn

    3. März 2009 um 12:11 Uhr

  • Für das, was es wert ist, lautet eine sehr gute Faustregel, dass Sie es wahrscheinlich falsch machen, wenn Sie etwas umwandeln müssen, damit es funktioniert – wie hier, wo Sie den char * -Puffer in BSTR umwandeln – dann machen Sie es wahrscheinlich falsch und sollten es tun Suchen Sie stattdessen nach einer anderen Konvertierung. Legitime Verwendungen von Gipsverbänden sind in der Regel ziemlich selten, daher ist es eine gute Idee, Gipsverbände mit Argwohn zu behandeln.

    – Brendan McK

    3. Mai 2012 um 20:52 Uhr

Benutzer-Avatar
Aidan Ryan

Verwenden _bstr_t:

_bstr_t bstrt(buffer);

Hier ist der Heiliger Gral der String-Konvertierungsartikel

  • _bstr_t ist eine Klasse. Nicht nützlich für reines C, nehme ich an.

    – scharfer Zahn

    3. März 2009 um 11:59 Uhr

Benutzer-Avatar
scharfer Zahn

Anruf MultiByteToWideChar()dann entweder SysAllocString() oder SysAllocStringLen().

Vergessen Sie nicht anzurufen SysFreeString() wenn Sie den BSTR nicht mehr benötigen.

Im Detail (SysAllocStringLen() Variante – sie ist kürzer und schneller):

  1. Anruf MultiByteToWideChar() und übergeben Sie 0 als fünften und sechsten Parameter. Es gibt die Anzahl der Zeichen im Unicode-Äquivalent der ANSI-Zeichenfolge zurück. Denken Sie daran, dass die ANSI-Zeichenfolge beliebige Zeichen enthalten kann, nicht nur ASCII, sodass alle Versuche, die Anzahl der Unicode-Zeichen anhand der Länge der ANSI-Zeichenfolge manuell zu berechnen, in einigen Fällen funktionieren und in anderen nicht funktionieren.

  2. Ordnen Sie mit einen Puffer für den BSTR zu SysAllocStringLen(). Übergeben Sie als ersten Parameter 0 und als zweiten Parameter die Anzahl der Unicode-Zeichen. Sie haben jetzt einen ordnungsgemäß zugewiesenen, aber nicht initialisierten BSTR. Es hat bereits Platz für die nachgestellte Null und diese nachgestellte Null ist richtig platziert.

  3. Anruf MultiByteToWideChar() zweites Mal und dieses Mal passieren die zugewiesenen BSTR dort. Die Funktion konvertiert die Zeichenfolge in Unicode und kopiert das Ergebnis in den BSTR. Jetzt haben Sie einen ordnungsgemäß zugewiesenen BSTR, der das Unicode-Äquivalent Ihrer ANSI-Zeichenfolge enthält.

  4. Übergeben Sie die BSTR an VB. Genießen.

  5. Anruf SysFreeString() BSTR freizugeben.

  • Mein Code funktioniert immer noch nicht, ich habe es so geändert. void Cfunc(char *buffer,int len) { BSTR buf_bstr; ULONG cZeichen; if (0 == MultiByteToWideChar(0, 0, buffer, cCharacters, buf_bstr, cCharacters)); VBptr.VBfunc(buf_bstr,len); } VB Exe ist abgestürzt.

    Josef_blr

    3. März 2009 um 12:47 Uhr

  • Hallo Sharptooth.. ich bin neu in diesem COM 🙁

    Josef_blr

    3. März 2009 um 12:51 Uhr

Benutzer-Avatar
David Syke

Dies ist der Code, den ich mit der Sharptooths-Antwort geschrieben habe

    int wslen = MultiByteToWideChar(CP_ACP, 0, str, strlen(str), 0, 0);
    BSTR bstr = SysAllocStringLen(0, wslen);
    MultiByteToWideChar(CP_ACP, 0, str, strlen(str), bstr, wslen);
    // Use bstr here
    SysFreeString(bstr);

Beachten Sie, dass die Verwendung von -1 für die Länge der Zeichenfolge dazu führt, dass das Null-Terminator im Ergebnis enthalten ist

Ich habe nichts gegen Ajryans Antwort einzuwenden, aber hier ist eine Alternative …

SysAllocString ist so definiert, dass es einen Parameter vom Typ OLECHAR * akzeptiert. Du gibst ihm ein Zeichen *. Das ist nicht dasselbe. Es gibt bestimmte Umstände, wenn sie könnte dasselbe sein, aber man kann sich nicht darauf verlassen. Also zuerst müssen Sie Ihr char * in ein OLECHAR * umwandeln. Es gibt ein Makro namens A2OLE, das dies für Sie tun kann, und in den Fällen, in denen char * und OLECHAR * dasselbe sind, wird das Makro zu nichts kompiliert (glaube ich).

Sehen diese Seite für Einzelheiten über A2OLE und seine Freunde.

Oh, und das Casting Ihres char * in einen BSTR ändert es überhaupt nicht, es ist weder ein BSTR noch ein OLECHAR *.

Probieren Sie anstelle von char*-Array _tchar*-Array aus. Da Sysallocstring nur die Unicode-Zeichen in einer 32-Bit-Anwendung akzeptiert.

1311970cookie-checkWie konvertiere ich char * in BSTR?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy