【发布时间】:2013-07-26 10:33:09
【问题描述】:
简单:如何显式编组 WinAPi 函数的结果?
我知道如何在 C# 中编组 WinApi 函数的参数,但我怎样才能编组返回值?还是我实际上必须编组它们?我了解 WinAPi 仅返回
BOOL 或所有类型的 INT (句柄在非托管代码中也是 int )。
// common signature
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
static extern int GetFileAttributes([MarshalAs(UnmanagedType.LPStr)] string filename);
// my prefered signature because easy to handle the result
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
static extern FileAttributes GetFileAttributes([MarshalAs(UnmanagedType.LPStr)] string filename);
由于FileAttributes 是枚举并且每个值都可以很容易地转换为int,所以我确信我对这个表示法是安全的。但是我可以像处理参数一样在这个签名中编组结果吗?我其实只知道Marshal 类和MarshalAs 属性。
【问题讨论】:
-
到底为什么要显式调用函数的 ANSI 版本? 1998 年到来,他们想要回他们的代码。
-
@CodyGray 因为谷歌和其他互联网上到处都是这个功能的 Ansi 版本。我已经制定了所有 3 个版本,但这只是一个示例。
-
我不太相信,但即使它是真的,那也不是正确的。至少,您需要
CharSet.Auto,但现在没有理由不使用CharSet.Unicode,除非您的目标是.NET 2.0 和Windows 98。 -
这不属于这里,但我与
Ansi一起工作直到今天我终于找到了如何使Auto工作。因为它没有。 pinvoke 没有为我的知识提供足够的信息。现在我已经为我的所有 WinApi 文件函数实现了所有 3 个签名,因此我可以在它们之间切换。如果你说Unicode是要走的路。我会记住这一点,并在下次考虑到它。好吗? -
您也必须使用适当的字符串类型,否则它将不起作用。那将是
UnmanagedType.LPWStr用于 Unicode,UnmanagedType.LPTStr用于 Auto。或者更好的是,完全省略MarshalAs属性,只使用默认编组。 CLR 知道它对字符串类型做了什么。
标签: c# winapi marshalling