6

3 つのパラメーターを取る API があります。

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

このメソッドを C# で使用するにはどうすればよいですか?

の等価性はLPCSTR何ですか? そして、の代わりに何を使用する必要がありHANDLEますか?

4

3 に答える 3

11

HANDLE同等のものは次のとおりですIntPtr(または、 のサブクラスの 1 つを使用できます。SafeHandleその多くは名前空間 で定義されていますMicrosoft.Win32.SafeHandles)。LPCSTRis stringorと同等ですStringBuilder(ただしstring、文字列をメソッドに渡し、メソッドはそれを変更しないため、より優れています)。a を使用することもできますbyte[](他の応答で書いたように、文字列をバッファーにエンコード\0し、最後に a を追加する必要があります...非常に不便です)。最後に、メソッドが変更しないLPCSTR定数です。他の応答で asLPSTRを設定することをお勧めします。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);

このバリアントは、常に同じ文字列でメソッドを何度も呼び出す必要がある場合に適しています。これは、文字列のエンコードされたバージョンをキャッシュして速度を上げることができるためです (はい、通常は役に立たない最適化です)。

于 2013-08-06T08:05:45.973 に答える
7

How to map Win32 types to C# types when using P/Invoke? によると、:

  • LPCSTR (C) - 文字列 (C#)
  • ハンドル (C) - IntPtr (C#)
于 2013-08-06T08:07:52.023 に答える