我正在为用 C 编写的游戏引擎编写一个托管包装器来挑战自己。我已经开始将非托管指针包装在SafeHandle
派生类中,但我认为调用可能返回相同指针的非托管函数可能会创建新的 SafeHandles,如果其中一个被释放,其余的将变得无效。
我怎样才能有效地防止这种情况发生?我怀疑编组器会自动跟踪重复项...
我正在为用 C 编写的游戏引擎编写一个托管包装器来挑战自己。我已经开始将非托管指针包装在SafeHandle
派生类中,但我认为调用可能返回相同指针的非托管函数可能会创建新的 SafeHandles,如果其中一个被释放,其余的将变得无效。
我怎样才能有效地防止这种情况发生?我怀疑编组器会自动跟踪重复项...
您正在尝试解决大多数托管指针和非垃圾收集技术试图解决的问题。根据用例,有多种解决方案 -
您可以使用引用计数 - 您基本上维护持有特定指针和重载(在 C 中使用函数调用而不是赋值)运算符的句柄数来更新赋值计数。然后,只有在计数达到 后才释放指针0
。这种方法虽然准确,但开销很大,而且容易受到循环的影响,因此可能会泄漏内存。这是一个引用计数所有权模型。
您可以创建一个unique_ptr
. 这基本上意味着在任何时候只有 1 个句柄持有对特定指针的引用。这意味着如果您执行以下操作 -
a = b
指针将从b
to复制a
并b
自动变为无效(更多的是 API 的合同,而不是实现)。这意味着用户必须围绕这些约束构建代码。当任何持有引用的对象超出范围时,这里就完成了释放。这是一种独占所有权模式。
还有其他方法(如weak_ptr
),您可以在任何 C++ 参考中阅读它们。
虽然这个答案是针对另一个问题的,但在这种情况下它会起作用。
我可以为我创建一个调用托管函数的工厂类,然后像 marhsaller 一样在Constrained Execution Region中手动创建 SafeHandles。这个工厂类可以跟踪非托管指针,如果已经创建了 SafeHandle,则返回它而不是创建一个新指针。