I’m communicating with a third party library where I need to acquire and the release an unmanaged resource. After some reading I came to the conclusion that best and ‘correct’ way to manage the resource reference was in either a SafeHandle or CriticalHandle object.
My problem arises because the handles returned by the third party library are unsigned short numeric values as opposed to pointers. If I specify the MarshalAsAttribute on the returned handle I get a MarshalDirectiveException (CriticalHandles must not have a MarshalAs attribute set and cannot be used in arrays).
Here are the things that I’ve considered:
- Marshal the handles in their numeric format and wrap them in a
CriticalHandlevia theCriticalhandle.SetHandleMethod. This allows the potential to leak a handle if an exception is raised between obtaining the reference and encapsulating it. - Marshal and store the handles in their numeric format. Have the containing type implement
CriticalFinalizerObject. This allows the potential to leak a handle if an exception is raised between obtaining the reference and encapsulating it. - Marshal the handles into a
SafeHandleas anIntPtr(letting the most significant 2 bytes fill with quasi-garbage). Cast theDangerousGetHandleback down to a short (discarding the most significant 2 bytes of garbage) every time I need to invoke a native method with theSafeHandle. This will prevent the any potential leaks of the handle but is very cumbersome and has the appearance of using brute force to make the wrong solution work.
How should I handle these ‘handles’?
As @HansPassant mentioned in a comment to my question:
It is therefore possible to marshal a C/C++ unsigned short directly into a derivative of
SafeHandle.