2014-02-09 7 views
6

Es ist mein Verständnis (und bitte korrigieren Sie mich, wenn ich falsch liege), dass der einzige Unterschied zwischen ihnen ist, ob die Zeichenfolge durch die aufgerufene Funktion geändert werden kann. (PCWSTR, LPWSTR)PCWSTR vs LPWSTR

Ich versuche jetzt, eine Zeichenfolge von C# zu einer Funktion eines PCWSTR erwarten zu passieren, aber alles, was ich finden kann, ist [MarshalAs(UnmanagedType.LPWStr)]. Habe ich Recht, dass das in Ordnung ist? (Ja, es arbeitet. Das aber ist kein Beweis dafür, dass es in Ordnung. Manche Arbeit aber dann Ursache Speicherlecks etc.)

Antwort

10

PCWSTR ist eine Zeitanachronismus, Dinosaurier-und-Menschen-Film-Stil. Das Finden eines 16-Bit-Programms, das kurze Zeiger auf eine Unicode-Zeichenfolge verwendet, ist wie das Suchen eines weißen Elefanten. Nur das Unterschied zwischen LPCWSTR und LPWSTR ist sinnvoll.

Das C in LPCWSTR ist einfach Annotation für Const, ein Schlüsselwort C-Sprache. Es verspricht, dass die aufgerufene Funktion niemals die übergebene Zeichenfolge ändert. Was in dieser Sprache sehr wichtig ist, ist es nicht sicher, ein String-Literal an ein LPWSTR-Argument zu übergeben. Dies führt sehr wahrscheinlich zum Absturz des Programms, wenn es versucht, die Zeichenfolge zu aktualisieren, und schlägt fehl, da die Speicherseite schreibgeschützt ist.

Und es ist wichtig, wenn Sie pinvoke. Das Übergeben einer System.String an ein LPCWSTR-Argument ist in Ordnung, Zeichenfolgen sind in .NET unveränderlich, sodass Sie eine Garantie erhalten, dass ein internes Zeichenfolgenliteral nicht beschädigt wird. Ein sehr schwer zu diagnostizierendes Problem. Die allgemeine Verwendung von [MarshalAs(UnmanagedType.LPWStr)] sollte nicht erforderlich sein. Sie würden die CharSet.Auto-Eigenschaft im Attribut [DllImport] verwenden und das LPWStr-Marshalling kostenlos abrufen. Wenn der Argumenttyp LPWSTR lautet, müssen Sie stattdessen einen StringBuilder übergeben. Mit einer ausreichenden Kapazität, um es dem systemeigenen Code zu ermöglichen, im Builder-Puffer herumzulaufen, um die Zeichenfolge zu schreiben.

+0

Vielen Dank. – ispiro

2

Eine Funktion einen PCWSTR Parameter genommen nicht, dass die Parameter verwenden kann, um Ändern Sie die Zeichen der Zeichenfolge im Gegensatz zu einer Funktion, die einen LPWSTR Parameter verwendet. Jedes Zeichen der Zeichenfolge wird als WCHAR gespeichert.

UnmanagedType.LPWStr ist der richtige Marshalling-Typ für eine solche Zeichenfolge.

+0

Sowohl PCWSTR als auch LPWSTR verwenden einen WCHAR, um ein Zeichen zu speichern. Das ist das "W" in ihrem Namen. – Dirk