在C#中,是否可以获得string
变量的char*
形式?
我需要将路径字符串转换为char*
以便于使用一些本地Win32函数...
你肯定可以这样做:
string str = "my string";
unsafe
{
fixed (char* p = str)
{
// do some work
}
}
有一个操作符(char*)绑定到字符串对象中。 然而,输出格式可能与底层的C或其他格式不兼容... 不过这是解析字符串的相当好的方法。 希望对任何阅读此帖子的人有所帮助。
以下代码段不需要任何不安全的上下文环境(是的,它展示了有关string
的GetHashCode
方法实现的内部细节,并显示了它与Java中的差异,因为在C#中,hashcode的值没有被缓存,通常表明C#字符串并不像你所学到的那样是绝对不可变的,不能处理Fon Neiman):
using System;
using System.Runtime.InteropServices;
namespace Guess
{
class Program
{
static void Main(string[] args)
{
const string str = "ABC";
Console.WriteLine(str);
Console.WriteLine(str.GetHashCode());
var handle = GCHandle.Alloc(str, GCHandleType.Pinned);
try
{
Marshal.WriteInt16(handle.AddrOfPinnedObject(), 4, 'Z');
Console.WriteLine(str);
Console.WriteLine(str.GetHashCode());
}
finally
{
handle.Free();
}
}
}
}
GCHandle.alloc
固定字符串指针不会导致内存泄漏,除非您在底层上下文中以后使用指针时强加了不当的用法。在C#中,整个指针/内存概念被认为是低级/高级话题,如果您使用指针,则意味着您理解整个概念并基本知道自己在做什么。 - Lu4结合之前两条回答,这取决于您参数的方向。
如果函数只需要一个输入字符串,即const char *
,则可以使用System.String
(或简单的string
)类型的参数。
如果函数填充一个字符串,即char * buffer, int bufferSize
,则可以传递System.Text.StringBuilder
。
在这两种情况下,(自动)封送将为您执行必要的转换。
StringBuilder
,但如果函数不会修改字符串,那似乎并不正确。 - mpen您可以使用Encoding.ASCII.GetBytes从字符串获取byte[]数组。 在C#中,可能可以使用fixed语句将其转换为char*。(这会固定分配的内存,不允许gc移动它-然后您可以创建指向它的指针)。
所以我的答案是肯定的,只要您成功将byte *转换为char *即可。 (在C / C ++中,这不是问题,但是我对C#不太确定)
附言>如果我找到一篇关于此的文章的书签,我将稍后发布一些代码。 我知道我有它的位置..
就像其他帖子指出的那样,fixed (char* p = str)
并不真正兼容本地格式,而StringBuilder
也并不真正起作用。这是对我有用的:
fixed (byte* p = Encoding.ASCII.GetBytes(str))
{
native_call((char*)p);
}
\0
。那么,本地可能会访问冲突或读取长度大于byte[] .Length。 - Trương Quốc Khánh
System.Char
元素的指针,它对应于Win32的WCHAR*
,但问题要求char *
。 - Tom Blodgetchar
是System.Char
的类型别名。 - Drew Noakeschar
解读为本地字符。现在意图对我来说不是很清晰。 - Tom Blodget