C#中的LPCSTR数据类型等效

时间:2013-08-06 07:59:02

标签: c#

我有一个API,它有三个参数:

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

如何在C#中使用此方法?

LPCSTR的等价性是什么?应该使用什么代替HANDLE

3 个答案:

答案 0 :(得分:9)

HANDLE等效项为IntPtr(或者您可以使用SafeHandle的子类之一,其中许多是在命名空间Microsoft.Win32.SafeHandles中定义的)。相当于LPCSTRstringStringBuilder(但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);

如果你必须多次使用相同的字符串调用方法,这个变体会更好,因为你可以缓存字符串的编码版本并获得速度(是的,通常它是无用的优化)

答案 1 :(得分:5)

根据How to map Win32 types to C# types when using P/Invoke?

  • LPCSTR(C) - 字符串(C#)
  • HANDLE(C) - IntPtr(C#)

答案 2 :(得分: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();