我有一个带三个参数的API
BOOL GetServerName (int index, LPSTR Buffer, int BufSize);
我如何在 C#
中使用此方法LPSTR 的等价性是什么?
答案 0 :(得分:5)
[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
将字符串传递给您。另一种方法是使用byte[]
并自己执行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字符串以空值终止。我们找到第一个带有\0
的{{1}},我们将字符转换为null为Array.IndexOf(buffer, (byte)0)
的字符串。
一些评论......
Encoding.Default.GetString()
),你应该使用它。如果存在,最好使用Unicode方法,因此不会丢失非Ansi字符。作为旁注,当您使用GetServerNameW
时,您应该检查您是否使用了正确的调用约定。对于Windows API,您不需要执行任何操作,但根据头文件中方法的定义方式,您可能需要添加DllImport
)。通常(但现在总是).NET运行时将在错误的调用约定上抛出异常,或者该方法将无法工作并返回奇怪的东西或将崩溃。这是因为调用约定告诉.NET必须如何将参数传递给方法(技术上在哪里,如何以及谁必须释放堆栈)。头文件中调用约定的一些示例是cdecl,stdcall,fastcall,thiscall,pascal(相当于stdcall),WINAPI,APIENTRY(相当于WINAPI),CALLBACK(相当于WINAPI)以及带有_或__前置的所有这些单词或在所有大写字母中。
Microsoft VC ++通常使用C方法的cdecl调用约定和C ++方法的thiscall。您可以通过某些arguments来控制它。