C# 安全与不安全代码

C# 安全与不安全代码,c#,unsafe,C#,Unsafe,今天读了关于安全和不安全代码的文章,然后我在中读到了,但我仍然不理解。为什么要在C#中使用指针?这纯粹是为了提高速度吗?有时,您需要使用指针将C#与底层操作系统或其他本机代码连接起来。你强烈反对这样做,因为这是“不安全的”(natch) 在一些非常罕见的情况下,您的性能受到CPU的限制,因此需要额外的一点点性能。我的建议是在assembler或C/C++的单独模块中编写这些CPU接口,导出一个API,并让您的.NET代码调用该API。另一个可能的好处是,您可以将特定于平台的代码放在非托管模块中,

今天读了关于安全和不安全代码的文章,然后我在中读到了,但我仍然不理解。为什么要在C#中使用指针?这纯粹是为了提高速度吗?

有时,您需要使用指针将C#与底层操作系统或其他本机代码连接起来。你强烈反对这样做,因为这是“不安全的”(natch)


在一些非常罕见的情况下,您的性能受到CPU的限制,因此需要额外的一点点性能。我的建议是在assembler或C/C++的单独模块中编写这些CPU接口,导出一个API,并让您的.NET代码调用该API。另一个可能的好处是,您可以将特定于平台的代码放在非托管模块中,并使.NET平台不受影响。

使用不安全代码有三个原因:

  • API(如John所述)
  • 获取数据的实际内存地址(例如,访问内存映射硬件)
  • 访问和修改数据的最有效方式(时间关键型性能要求)

    • 我倾向于避免它,但有时它非常有用:

      • 用于处理原始缓冲区(图形等)的性能
      • 需要一些非托管API(对我来说也很少见)
      • 用数据作弊
      例如,在最后一个示例中,我维护了一些序列化代码。在流中写入
      浮点
      ,而不必使用
      位转换器.GetBytes
      (每次都会创建一个数组)是很痛苦的-但我可以欺骗:

      float f = ...;
      int i = *(int*)&f;
      

      现在我可以使用shift(
      >
      )等来编写
      I
      比编写
      f
      要容易得多(字节数将与调用
      BitConverter.GetBytes
      时相同,加上我现在通过选择使用shift来控制尾数).

      至少有一个托管的.Net API经常使使用指针变得不可避免。见和


      获取
      安全字符串的纯文本值的唯一方法是使用
      封送
      方法之一将其复制到非托管内存。

      为什么建议为性能敏感的代码切换语言?好处并不明显。为什么不使用C语言的全部功能?为正确的工作使用正确的工具?如果我要胡闹指针和其他低级工作,我宁愿用C/C++来做,因为我有很多工具可以使用。C#不支持内联汇编程序、基于指针和其他位推送功能。我同意,在用汇编程序或C编写代码时,您需要关注代码的编译方式。即使使用不安全的C#,您仍然在托管环境中工作。JIT可以针对正确的CPU,并在适当的时候执行其他优化(如内联方法)。如果您不需要其他语言的额外功能,并且您已经在用C#编写代码,并且您想通过指针操作来提高性能,那么我认为“不安全”C#是正确的选择。我可以同意您的看法,如果您所做的只是在内存块上跳华尔兹舞,而不是调用特定于平台的功能,留在C#的范围内可能是合理的@Henri:您应该尝试确保您的非托管API足够细粒度,这样您就不需要在编组将消耗您的性能的紧密循环中调用它。就像你不通过调用SetPixel()width*height times来绘制位图,而是调用BitBlt。对于时间关键型应用程序,使用.net无论如何都不明智。GC是不确定的,可以随时启动。这基本上把你的时间关键型应用搞砸了。其他几点我也同意!我听说使用不安全C#的另一个原因是确保在确定的时间点从内存中删除安全敏感信息,如密码或私有加密密钥。否则,密码可能会一直挂在内存中,直到其他人想写入相同的位置。我理解你为什么这么做,但C语言的代码让我感到畏缩。当我看到这段代码时,我忍不住笑了起来:
      因为数据作弊
      。你让我崩溃了,我的朋友!我不能说我做过,但这个例子很有道理!如果你是一个明智的人,那么你永远不会想在C#中使用指针。它们适用于您必须在C中使用指针的情况,无论您是否愿意。:-)