我有一个接受三个参数的 API
BOOL GetServerName (int index, LPSTR Buffer, int BufSize);
我如何在C#中使用此方法
LPSTR的等价物是什么?
[DllImport("YourDll.dll", CharSet = CharSet.Ansi)]
//[return: MarshalAs(UnmanagedType.Bool)] // This line is optional, and it's implicit
static extern bool GetServerName(int index, StringBuilder buffer, int bufSize);
要使用它:
int bufSize = 100;
StringBuilder buffer = new StringBuilder(bufSize);
bool result = GerServerName(0, buffer, bufSize);
if (result)
{
string buffer2 = buffer.ToString();
}
从技术上讲,您的问题是“什么相当于 LPSTR”... 响应是:string
或者StringBuilder
如果您将字符串传递给方法,StringBuilder
如果方法将字符串传递给您。另一种选择是使用 abyte[]
并Encoding/Decoding
自己做,例如:
[DllImport("YourDll.dll", CharSet = CharSet.Ansi)]
//[return: MarshalAs(UnmanagedType.Bool)] // This line is optional, and it's implicit
static extern bool GetServerName(int index, byte[] buffer, int bufSize);
和
int bufSize = 100;
byte[] buffer = new byte[bufSize];
bool result = GerServerName(0, buffer, bufSize);
if (result)
{
string buffer2 = Encoding.Default.GetString(buffer, 0, Array.IndexOf(buffer, (byte)0));
}
(C 字符串以 null 结尾。我们找到第一个\0
withArray.IndexOf(buffer, (byte)0)
并将字符转换为 null 为字符串 with Encoding.Default.GetString()
)。
一些评论...
GetServerNameW
),您应该使用它。如果存在,最好使用 Unicode 方法,这样非 Ansi 字符就不会丢失。作为旁注,当您使用 时DllImport
,您应该检查您是否使用了正确的调用约定。对于 Windows API,您不需要做任何事情,但根据头文件中方法的定义方式,您可能需要添加CallingConvention = CallingConvention.something
)。通常(但现在总是).NET 运行时会在错误的调用约定上抛出异常,或者该方法将不起作用并返回奇怪的东西或崩溃。这是因为调用约定告诉 .NET 必须如何将参数传递给方法(从技术上讲,在何处、如何以及谁必须释放堆栈)。头文件中调用约定的一些示例是 cdecl、stdcall、fastcall、thiscall、pascal(相当于 stdcall)、WINAPI、APIENTRY(相当于 WINAPI)、CALLBACK(相当于 WINAPI)以及所有这些带有 _ 或 __ 前缀或全部大写。Microsoft VC++ 通常对 C 方法使用 cdecl 调用约定,对 C++ 方法使用 thiscall。你可以通过一些参数来控制它。