【发布时间】:2010-05-28 02:31:30
【问题描述】:
使用过 Windows API 的 P/Invoke 的每个人都知道一长串具有如下属性的静态函数声明
[DllImport ("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
从 WinNT.h 等 Windows 头文件或 www.pinvoke.net 等网站复制的结构声明在我们的程序中也占据了很多位置。
为什么我们都必须为此花时间?为什么微软不给我们一个简单的方法来在旧的非托管程序中包含一行
#include <windows.h>
我们将可以访问一个静态类Native,其中包含所有或大多数 Windows 函数和结构?
更新基于一些答案:
您对自己诚实一点,您的 .NET 程序的哪一部分不是在 Windows 下运行的? 5%? 1%?如果您在 .NET 中使用 WMI、Process、Registry 或 ServiceProcess.ServiceBase 类等,那么您的程序就是“平台无关”和更多“兼容”如果您不使用原生 API? Thread.ApartmentState 是否在 Windows 之外无处不在?
使用SafeHandle 或try {…} finally 是有必要的。我很乐意有任何这些形式的 Native API 的标准定义。
我知道windows.h 中的某些结构具有不同的版本 32/64 或 XP/Vista 等。我认为拥有不同版本的 Native 结构就足够了,例如 MIB_IPADDRROW_XP 和 MIB_IPADDRROW_W2K 或 IMAGE_NT_HEADERS32和IMAGE_NT_HEADERS64(请参阅 Windows 标题中的相同名称)。
如果存在托管.NET 类和方法,则应该使用它。遗憾的是,Windows 的一些最强大的功能在托管 .NET 中的实现为时已晚,而且到目前为止,很多功能只能在非托管世界中访问。 10 年前,在第一次关于 .NET 的 Microsoft 会议上,我询问了我对 Memory Mapped Files 的青睐。现在只有 .NET 4 实现了 MemoryMappedFile 类(请参阅 http://blogs.msdn.com/salvapatuel/archive/2009/06/08/working-with-memory-mapped-files-in-net-4.aspx)。如果为了管理目的而编写实用程序,同样的问题会永久存在。例如,用CreateFile 和标志FILE_FLAG_BACKUP_SEMANTICS 或RegCreateKeyEx 用REG_OPTION_BACKUP_RESTORE 或REG_OPTION_CREATE_LINK 打开文件。 硬链接和Junctions(参见http://msdn.microsoft.com/en-us/library/aa365006(v=VS.85).aspx)是下一个示例。再举一个例子:使用 Job Objects 而不是 Process(参见 http://msdn.microsoft.com/en-us/library/ms684161(VS.85).aspx 和 http://www.microsoft.com/msj/0399/jobkernelobj/jobkernelobj.aspx)。如果你想启动一个进程并等到这个进程,还要等到它的所有子进程结束,job 是非常有用的。可以使用CreateJobObject 和AssignProcessToJobObject,然后使用TerminateJobObject 或WaitHandle,例如.NET 版本的(WaitForSingleObject)。
仅在 .NET 4.0 System.IntPtr 和 System.UIntPtr 类中支持 Add 和 Subtract 方法。
我可以继续这些例子,但我希望你明白我的意思。所以我想用 .NET 编写一个程序,因为它有很多优点,但我并不总是可以在不使用本机 API 的情况下做到这一点。此外,有时客户对软件实现的语言有要求,我会选择需要的方式。
更新 2:Microsoft 改进了与 .NET 4.0 中的 COM 的互操作性,但没有改进与 C 类 Windows API 的互操作性。我看到了一些使使用 P/Invoke 更容易的方法。你看有什么办法做到这一点?我建议我看到的三个方向:
- 使用声明所有(或最重要的)尚未在 .NET Windows API 中完全实现的程序集。这个汇编只能(或几乎只有)具有静态函数和相应类/结构的静态 Native 类的元数据。这个程序集可以放在 GAC 中,每个人都可以使用它。 (这种方式我测试过。效果很好。)
- 实现了一组 sn-ps,其中包含使用不同原生 Windows API 的声明和示例。
- 在 www.codeplex.com 上启动一个开源项目,在该项目中创建 .NET 类和一些最重要的本机 Windows API 的扩展方法,这些 API 尚未在 .NET 中实现。
我确信存在更多方法可以让开发人员更轻松地使用本机 Windows API。欢迎提出其他建议。
【问题讨论】:
标签: c# .net windows interop pinvoke