在C#中与LPCSTR数据类型等效的是什么?

6

我有一个API需要三个参数:

HANDLE  Connect(LPCSTR MachineName, LPCSTR ServerName, BOOL EnableDLLBuffering); 

如何在C#中使用这个方法?

LPCSTR的等价物是什么?在HANDLE的位置上应该使用什么?


1
这个问题怎么不是重复的?在 Stack Overflow 存在的 5 年时间里(大约 5,493,950 个问题),肯定已经有人问过了。 - Peter Mortensen
1
@PeterMortensen 如果您认为它是重复的,那么您应该将其标记为重复。我所能找到的都是关于一般P/Invoke问题的问题。 - user247702
1
LPCSTR是指向常量字符字符串的指针,即const char*,这在C#中表示字符串。另外,HANDLE可以用C#中的IntPtr替换。 - ahmedsafan86
建议的重复内容并不是很好。被接受的回答指向了一个CodeProject文章,甚至没有包括SafeHandle,也没有讲述如何手动编码字符串。 - xanatos
xanatos: 我同意。有谷歌功夫的人,站出来! - Peter Mortensen
3个回答

11

HANDLE的等效类型是IntPtr(或者你可以使用SafeHandle的其中一个子类,其中许多都定义在命名空间Microsoft.Win32.SafeHandles中)。LPCSTR的等效类型是stringStringBuilder(但是string更好,因为你将字符串传递给方法且方法不会修改它)。你甚至可以使用byte[](正如我在另一个回答中所写的,但你必须在缓冲区中对字符串进行编码,并在结尾添加\0...这相当不方便)。最终,LPCSTR是方法不会修改的常量LPSTR。最好像另一个回答中那样设置CharSet.Ansi

[DllImport("YourDll.dll", CharSet = CharSet.Ansi)]
static extern IntPtr Connect(string machineName, string serverName, bool enableDLLBuffering);

你称之为:

IntPtr ptr = Connect("MyMachine", "MyServer", true);

或者,如果你真的想要自己进行编码:

[DllImport("YourDll.dll", CharSet = CharSet.Ansi)]
static extern IntPtr Connect(byte[] machineName, byte[] serverName, bool enableDLLBuffering);

public static byte[] GetBytesFromStringWithZero(Encoding encoding, string str)
{        
    int len = encoding.GetByteCount(str);

    // Here we leave a "space" for the ending \0
    // Note the trick to discover the length of the \0 in the encoding:
    // It could be 1 (for Ansi, Utf8, ...), 2 (for Unicode, UnicodeBE), 4 (for UTF32)
    // We simply ask the encoder how long it would be to encode it :-)
    byte[] bytes = new byte[len + encoding.GetByteCount("\0")];
    encoding.GetBytes(str, 0, str.Length, bytes, 0);
    return bytes;
}

IntPtr ptr = Connect(
                 GetBytesFromStringWithZero(Encoding.Default, "MyMachine"),
                 GetBytesFromStringWithZero(Encoding.Default, "MyServer"), 
                 true);

如果您需要多次调用该方法并且使用相同的字符串,则此变体更好,因为您可以缓存字符串的编码版本并在速度上获得一些优势(是的,通常这是一种无用的优化)


LPCSTR 可以,但是 Handle 怎么用?你能告诉我如何在我的程序中使用它吗? - mahua22
@mahua22 HANDLE 是一个不透明的类型。你可以将它传递给其他使用它的方法。库应该有一些接受 HANDLE 的方法,并且应该有一个 CloseHandle 方法来在最后关闭它(否则会导致泄漏)。 - xanatos

7

3
这个问题涉及到的是LPCTSTR,而不是LPCSTR。我不知道它们是否等同,只是想提一下。 - user247702
@user247702 这个问题是关于 LPCSTR 的。 - bg117

1
我使用 StringBuilder:
    [DllImport("user32.dll", CharSet = CharSet.Ansi)]
    static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

    var sb = new StringBuilder();
    var ret = GetClassName(hwnd, sb, 100);
    var klass = sb.ToString();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接