gpt4 book ai didi

c# - 在传递给非托管代码之前固定一个可更新的结构?

转载 作者:可可西里 更新时间:2023-11-01 09:08:37 25 4
gpt4 key购买 nike

我使用一些旧的 API,需要将结构的指针传递给异步运行的非托管代码。

换句话说,在我将结构指针传递给非托管代码后,非托管代码复制该指针并立即返回。非托管代码可以在另一个线程的后台访问该结构。 我无法控制在另一个线程中运行的非托管代码,也无法控制线程本身。

固定的 { } 语句不能用于固定,因为它不是为异步非托管固定而设计的。

GCHandle 只能固定引用,因此必须对结构进行装箱才能使用 GCHandle。我试过了,它有效。它的主要问题是您无法从托管代码 更新结构。要更新结构,首先我们需要将其拆箱,然后更新,然后再次装箱,但是......哎呀......再次装箱?!?这意味着内存中的前一个指针仍然指向旧的非最新结构,而新结构有另一个指针,这意味着我需要将新指针传递给非托管代码......不适用于我的案例。

我如何在没有固定 { } 语句的情况下将结构固定在内存中,以便我可以在不更改其指针的情况下从托管代码更新它?

谢谢。

编辑:

只是想...有没有办法固定包含结构的父对象,然后获取结构的指针而不是容器对象?

最佳答案

在这种情况下使用固定内存不是一个好主意,因为结构的内存需要长期有效。 GCHandle.Alloc() 会将结构装箱并将其存储在堆上。随着它被固定,这将成为垃圾收集器的长期负担,因为它需要不断地寻找绕过路上岩石的方法。

简单的解决方案是在非托管内存中为结构体分配内存。使用 Marshal.SizeOf() 获取结构的大小,使用 Marshal.AllocCoTaskMem() 分配内存。这使您获得了需要传递给非托管代码的指针。使用 Marshal.StructureToPtr() 初始化内存。并使用 PtrToStructure() 读取非托管代码编写的结构的更新。

如果您经常这样做,您将不断地复制结构。这可能很昂贵,具体取决于结构的大小。为避免这种情况,请使用不安全指针直接访问非托管内存。一些基本语法:

using System;
using System.Runtime.InteropServices;

class Program {
unsafe static void Main(string[] args) {
int len = Marshal.SizeOf(typeof(Test));
IntPtr mem = Marshal.AllocCoTaskMem(len);
Test* ptr = (Test*)mem;
ptr->member1 = 42;
// call method
//..
int value = ptr->member1;
Marshal.FreeCoTaskMem(mem);
}
public struct Test {
public int member1;
}
}

关于c# - 在传递给非托管代码之前固定一个可更新的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1850488/

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