gpt4 book ai didi

c# - 为什么Microsoft不为C#提供一个静态Win32类,而该类具有Windows.h之类的内部最原生的函数和结构?

转载 作者:可可西里 更新时间:2023-11-01 13:28:05 29 4
gpt4 key购买 nike

使用Windows API P/Invoke的每个人都知道带有诸如以下属性的静态函数声明的一长串列表

 [DllImport ("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

从Windows header (如WinNT.h)或网站(如www.pinvoke.net)复制的结构声明在我们的程序中也占有很多位置。

为什么我们所有人都必须为此花费时间?为什么Microsoft不给我们一种简单的方法来像在旧的非托管程序中那样包含一行
#include <windows.h>

并且我们将可以访问具有所有或大多数Windows功能和结构的静态类 Native

根据一些答案更新了:

您将自己诚实地说,.NET程序的哪些部分不在Windows下运行? 5%? 1%?如果在.NET中使用 WMI 进程注册表 ServiceProcess.ServiceBase 类等,那么您的程序是否“独立于平台”,并且如果不使用 native API则更“兼容”? Windows到处都有 Thread.ApartmentState吗?

必须使用 SafeHandletry {…} finally。我很高兴以任何这些形式获得 native API的标准定义。

我知道 windows.h中的某些结构具有不同版本的32/64或XP/Vista等。我认为拥有不同版本的 native 结构(例如 MIB_IPADDRROW_XPMIB_IPADDRROW_W2KIMAGE_NT_HEADERS32IMAGE_NT_HEADERS64)就足够了(在Windows header 中看到相同的名称) 。

如果存在的话,应该使用托管的.NET类和方法。遗憾的是,Windows的一些最强大功能的实现在托管的.NET中为时已晚,到目前为止,其中许多功能只有在非托管的世界中才能访问。 10年前,在第一次有关.NET的Microsoft session 上,我询问了我的青睐 内存映射文件。现在只有.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_SEMANTICSRegCreateKeyEx标记 REG_OPTION_BACKUP_RESTOREREG_OPTION_CREATE_LINK硬链接(hard link)交界处(请参阅 http://msdn.microsoft.com/en-us/library/aa365006(v=VS.85).aspx)是下一个示例。另一个示例:使用 作业对象而不是Process(请参阅 http://msdn.microsoft.com/en-us/library/ms684161(VS.85).aspxhttp://www.microsoft.com/msj/0399/jobkernelobj/jobkernelobj.aspx)。如果您要开始一个过程,而又不等到这个过程,也要等到所有子过程都结束时,工作就非常有用。可以先使用 CreateJobObjectAssignProcessToJobObject,然后再使用 TerminateJobObjectWaitHandle,例如( WaitForSingleObject)的.NET版本。

仅在.NET 4.0中 System.IntPtrSystem.UIntPtr类支持 AddSubtract方法。

我可以继续这些示例,但我希望您理解我的意思。因此, 由于很多优点,我想在.NET中编写程序,但是如果不使用 native API ,我可能无法始终做到这一点。而且,有时客户对软件实现的语言有要求,我会选择所需的方式。

更新2 :Microsoft改进了.NET 4.0中与COM的互操作性,但没有改进类似于C的Windows API。我看到了一些使P/Invoke的工作更轻松的方法。您看到了什么方法?我建议我看到三个方向:
  • 用.NET Windows API中尚未完全实现的所有(或最重要的)声明进行组装。该程序集只能(或几乎只有)具有静态Native类的元数据以及静态函数和相应的类/结构。该程序集可以放置在GAC中,每个人都可以使用它。 (通过这种方式测试。效果很好。)
  • 一个实现带有声明和使用不同 native Windows API的示例的摘录的集合。
  • 一个人在www.codeplex.com上启动一个开源项目,在其中创建一个.NET类和对一些最重要的 native Windows API的扩展方法,这些方法尚未在.NET中实现。

  • 我确信,存在更多使开发人员更容易使用 native Windows API的方法。欢迎其他建议。

    最佳答案

    我不知道为何MSFT做出此决定,但以下是我认为该决定是正确的决定的一些原因:

  • Windows SDK头文件(windows.h等)广泛使用基于目标Windows版本和体系结构之类的条件编译来确定要声明的函数以及数据结构的布局。在任何一种.NET语言中,这些都不是不可能的,因为它不是针对Windows版本而是针对框架版本,因此生成的二进制文件能够在Windows的许多版本上的32位和64位体系结构上本地运行
  • 许多Windows API调用和数据结构无法通过P/Invoke完整表达。我想到的一个是DeviceIoControl。另一个是许多所谓的“可变长度”结构,其中包含数组,这些数组中的元素数量未知(在编译时)
  • P/Invoke随时间而发展,特别是在暴露句柄的方式上(框架的早期版本中为IntPtr;稍后为SafeHandle类);如果MSFT维护具有大多数或全部Win32 API函数的单个静态类,则它们也必须与该类的先前版本保持兼容性,从而将其锁定为P/Invoke最初是由
  • 实现的
  • 即使MSFT本身也不在框架内部维护单个Native类。现在,.NET Framework 3.5源代码可用,您可以亲自看到P/Invoke的即席使用,即使在我们应该用来替代P/Invoke的框架内也是如此。例如,System.Net和System.IO具有各自独立的P/Invoke声明。
  • .NET Framework和托管代码从一开始就被设计为构建Windows软件的新方法。提供这种新方法,同时又需要对许多任务使用旧方法,这会是多么愚蠢?

  • 我说这是作为IOCTL和卷级I/O操作之类的P/Invoke广泛使用的人。我使用P/Invoke的次数越多,我就越讨厌它。它很难使用,容易出错,而且速度很慢。每次我使用P/Invoke时,都是因为我用尽了所有其他选项。如果您发现自己的问题需要很多直接的Windows API调用来解决,则可能是:

    a)缺少框架中的某些功能,可以满足您的需求

    b)使用错误的方法来解决问题,尤其是如果您已习惯使用 native Windows API并仍然以这些方式考虑

    c)应该用C++/CLI编写低级代码,并公开矮小的高级接口(interface)供您的.NET代码使用

    关于c# - 为什么Microsoft不为C#提供一个静态Win32类,而该类具有Windows.h之类的内部最原生的函数和结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2792493/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com