c# - C++ LPSTR 到 C# 字符串 .Net Wrapper

标签 c# .net string pinvoke

我有一个接受三个参数的 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”... 如果您将字符串传递给方法,则响应是:stringStringBuilderStringBuilder 如果方法将字符串传递给您。另一种选择是使用 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 字符串以空结尾。我们找到第一个 \0Array.IndexOf(buffer, (byte)0) 并将字符转换为使用 Encoding.Default.GetString()) 将 null 转换为字符串。

一些评论...

  1. 我希望你有缓冲区的最大长度(就像一个常量),因为通常这些方法被写成以某种方式返回字符串的长度。
  2. 如果您有该方法的 Unicode 版本(可能是 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。你可以通过一些arguments来控制它.

关于c# - C++ LPSTR 到 C# 字符串 .Net Wrapper,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18073857/

相关文章:

excel - 使用替换功能将一个字符替换为两个

c# 正则表达式到 javascript

c# - 在 c# (LINQ-2-Entities) 中实现 "IN"的自定义扩展函数

c# - 从 C# 中的非托管 C++ DLL 获取字节数组上的指针

c# - 是否可以创建相同的 guid

c# - 是否可以发布 ASP.NET 5 应用程序以使目标计算机不需要安装 DNX?

C#/.NET - 使用异步/等待函数调用时 CPU 使用率非常高

PHP 检查字符串是否包含不带 http 的 url ://

c# - 指定的版本字符串不符合要求的格式 - major[.minor[.build[.revision]]]

java - 为什么池中存在两个具有相同数据的文字