我使用一些旧的API,需要将一个结构体的指针传递给运行异步的非托管代码.
换句话说,在将struct指针传递给非托管代码之后,非托管代码复制指针并立即返回.非托管代码可以在另一个线程的后台访问该结构体.我无法控制在另一个线程中运行的非托管代码,也不能控制线程本身.
固定的{}语句不能用于固定,因为它不是为异步非托管固定而设计的.
GCHandle只能引用引用,所以结构体必须装箱使用GCHandle.我试过,它的作品.它的主要问题是您无法从托管代码更新结构.要更新一个结构,首先我们需要unBox它,然后更新,然后再次框,但… oops …框再次?这意味着内存中的前一个指针仍然指向旧的非最新的结构体,新的结构体有另一个指针,这意味着我需要将新的指针传给非托管代码…不适用于我的案件.
如何在内存中固定一个结构体,而不需要固定的{}语句,所以我可以从托管代码更新它,而不改变它的指针?
谢谢.
编辑:
解决方法
不安全的代码是一个选项吗?
// allocate unmanaged memory Foo* foo = (Foo*)Marshal.AllocHGlobal(sizeof(Foo)); // initialize struct foo->bar = 0; // invoke unmanaged function which remembers foo UnsafeNativeMethods.Bar(foo); Console.WriteLine(foo->bar); // update struct foo->bar = 10; // invoke unmanaged function which uses remembered foo UnsafeNativeMethods.Qux(); Console.WriteLine(foo->bar); // free unmanaged memory Marshal.FreeHGlobal((IntPtr)foo);
这个编译并没有抛出异常,但我手头没有非托管功能来测试它是否工作.
从MSDN:
When AllocHGlobal calls LocalAlloc,it passes a LMEM_FIXED flag,which causes the allocated memory to be locked in place. Also,the allocated memory is not zero-filled.