PCWSTR和LPWSTR [英] PCWSTR vs LPWSTR
问题描述
根据我的理解(如果我错了,请纠正我),它们之间的唯一区别是所调用的函数是否可以修改字符串。 ( PCWSTR , LPWSTR )
It is my understanding (and please correct me if I'm wrong) that the only difference between them is whether the string might be modified by the called function. (PCWSTR , LPWSTR)
我现在正在尝试将C#中的字符串传递给需要 PCWSTR 的函数,但是我只能找到 [MarshalAs(UnmanagedType.LPWStr)]
。我正确吗? (是的,它有效。但这并不是很好的证明。有些事情有效,但随后会导致内存泄漏等。)
I am now trying to pass a string from C# to a function expecting a PCWSTR, but all I can find is [MarshalAs(UnmanagedType.LPWStr)]
. Am I correct that that is fine? (Yes, it works. That, though, is not a proof that it's fine. Some things work but then cause memory leaks etc.)
推荐答案
PCWSTR是一种时间不合时宜的恐龙与人类电影风格。查找在Unicode字符串上使用短指针的16位程序就像查找白象。只有LPCWSTR和LPWSTR之间的区别才有意义。
PCWSTR is a time anachronism, dinosaur-and-humans movie style. Finding a 16-bit program that uses short pointers on a Unicode string is like finding a white elephant. Only the distinct between LPCWSTR and LPWSTR is meaningful.
LPCWSTR中的C只是对 const (一种C语言关键字)的注释。它保证被调用函数永远不会修改您传递的字符串。用该语言知道这点非常重要,将字符串文字传递给LPWSTR参数并不安全。
The C in LPCWSTR is simply annotation for const, a C language keyword. It promises that the called function never modifies the string that you pass. Which is very important to know in that language, it is not safe to pass a string literal to a LPWSTR argument. That is very likely to crash the program when it tries to update the string and fails because the memory page is read-only.
这很可能在程序尝试更新字符串时使程序崩溃并失败,因为内存页是只读的。将System.String传递给LPCWSTR参数很好,因为字符串在.NET中是不可变的,所以您可以保证不会被破坏。一个很难诊断的问题。通常不需要显式使用 [MarshalAs(UnmanagedType.LPWStr)]
,您可以在[DllImport]属性中使用CharSet.Auto属性并获取LPWStr封送处理
And it matters when you pinvoke. Passing a System.String to a LPCWSTR argument is fine, strings are immutable in .NET so you'll get a guarantee that an interned string literal isn't going to get mangled. A very hard to diagnose problem. Using [MarshalAs(UnmanagedType.LPWStr)]
explicitly should not be necessary in general, you'd use the CharSet.Auto property in the [DllImport] attribute and get the LPWStr marshaling for free.
,但是如果参数类型为LPWSTR,则必须传递一个StringBuilder。具有足够的容量以允许本机代码在构建器缓冲区中戳入以写入字符串。
But if the argument type is LPWSTR then you must pass a StringBuilder instead. With a sufficient Capacity to allow the native code to poke around in the builder buffer to write the string.
这篇关于PCWSTR和LPWSTR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!