我有一个API需要三个参数:
HANDLE Connect(LPCSTR MachineName, LPCSTR ServerName, BOOL EnableDLLBuffering);
如何在C#中使用这个方法?
LPCSTR
的等价物是什么?在HANDLE
的位置上应该使用什么?
我有一个API需要三个参数:
HANDLE Connect(LPCSTR MachineName, LPCSTR ServerName, BOOL EnableDLLBuffering);
如何在C#中使用这个方法?
LPCSTR
的等价物是什么?在HANDLE
的位置上应该使用什么?
HANDLE
的等效类型是IntPtr
(或者你可以使用SafeHandle
的其中一个子类,其中许多都定义在命名空间Microsoft.Win32.SafeHandles
中)。LPCSTR
的等效类型是string
或StringBuilder
(但是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);
如果您需要多次调用该方法并且使用相同的字符串,则此变体更好,因为您可以缓存字符串的编码版本并在速度上获得一些优势(是的,通常这是一种无用的优化)
HANDLE
是一个不透明的类型。你可以将它传递给其他使用它的方法。库应该有一些接受 HANDLE
的方法,并且应该有一个 CloseHandle
方法来在最后关闭它(否则会导致泄漏)。 - xanatosLPCTSTR
,而不是LPCSTR
。我不知道它们是否等同,只是想提一下。 - user247702LPCSTR
的。 - bg117 [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();
SafeHandle
,也没有讲述如何手动编码字符串。 - xanatos