gpt4 book ai didi

.net - 管理到非管理开销

转载 作者:行者123 更新时间:2023-12-04 06:46:28 25 4
gpt4 key购买 nike

在 .NET 中,有几个地方您必须离开托管代码并进入非托管(也称为 native 代码)领域。仅举几例:

  • 外部 dll 函数
  • COM 调用

  • 总是有关于从一侧跳到另一原因的开销的评论,我的问题是,是否有人测量了正在发生的确切开销,并可以解释如何计算它。例如,也许 byte[]可以转换为 IntPtr甚至到 byte*在 .NET 中并帮助编码器节省一些 CPU 周期。

    最佳答案

    确实可以获取托管数组的地址。

    首先,您必须使用 System.Runtime.InteropServices.GCHandle 固定阵列。 ,这样垃圾收集器就不会移动数组。只要非托管代码可以访问托管数组,就必须保持分配此句柄。

    byte[] the_array = ... ;
    GCHandle pin = GCHandle.Alloc(the_array, GCHandleType.Pinned);

    然后,您应该可以使用 System.Runtime.InteropServices.Marshal.UnsafeAddrOfPinnedArrayElement获取数组中任何元素的 IntPtr。
    IntPtr p = Marshal.UnsafeAddrOfPinnedArrayElement(the_array,0);

    重要提示:固定对象会严重破坏 GC 操作。能够在堆中移动对象是现代 GC 可以(在某种程度上)跟上手动内存管理的原因之一。通过将对象固定在托管堆中,GC 失去了与手动内存管理相比的一个性能优势:相对没有碎片的堆。

    因此,如果您打算将这些数组“在非托管端”保留一段时间,请考虑制作数组的副本。复制内存速度惊人。使用 Marshal.Copy(*)从托管内存复制到非托管内存的方法,反之亦然。

    关于.net - 管理到非管理开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7074054/

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