我有一个返回NativeList<>
结构AStruct
的方法,其中NativeList<>
是实现IDisposable
的非托管内存的包装。 AStruct包含由NativeList<float>
支持的另一个指针,该指针也是用相同的方法创建的,因此:
private unsafe NativeList<AStruct> GetAStructs()
{
var floatList = new NativeList<float>();
floatList.Add(0.0f);
var list = new NativeList<AStruct>();
AStruct a1 = new AStruct();
a1.floats = (float*)floatList.Data;
list.Add(a1);
// ...
return list;
}
这是一个问题,因为现在在调用floatList
之后不再引用GetAStructs()
。因此,我已经更改了方法签名以包含out参数。
private unsafe NativeList<AStruct> GetAStructs(out IDisposable toDispose)
{
// ...
toDispose = floatList;
return list;
}
我这样称呼它
using (NativeList<AStruct> disposableList = GetAStructs(out IDisposable toDispose))
using (toDispose)
{
callNativeFunction((AStruct*)disposableList.Data);
}
这项工作会按预期进行吗?有没有办法在不向调用方法公开实现细节的情况下做到这一点?
答案 0 :(得分:1)
我承认我对NativeArray不太了解,但是在这种情况下,通常可以通过创建要使用的类的子类来获得所需的功能。
在这种情况下,建议您创建NativeList
的子类,其中包括要处理的回调。向其传递一个函数,该函数将完成您之前要求调用者执行的工作。
示例子类:
class MyNativeList<T> : NativeList<T>
{
protected readonly Action _callAfterDisposal;
public MyNativeList(Action callAfterDisposal) : base()
{
_callAfterDisposal= callAfterDisposal;
}
public override Dispose()
{
base.Dispose();
_callAfterDisposal();
}
}
设置回调:
private unsafe NativeList<AStruct> GetAStructs()
{
var floatList = new NativeList<float>();
floatList.Add(0.0f);
//here we construct the MyNativeList and pass it an action to execute when it is disposed
var list = new MyNativeList<AStruct>( () => {
callNativeFunction((AStruct*)floatList.Data);
floatList.Dispose();
});
AStruct a1 = new AStruct();
a1.floats = (float*)floatList.Data;
list.Add(a1);
// ...
return list;
}
执行此操作时,浮点数的本机列表将捕获在一个封闭变量中。您的呼叫者只需要按常规处理该列表,并且在进行回调时,也会处理本机的float列表。
using ( var disposableList = GetAStructs() )
{
//Do stuff
}
请注意,GetAStructs()
仍返回对NativeList<T>
的引用(不是MyNativeList<>
),因此实现细节不会泄漏给调用者,除非它们竭尽所能地投射结果。