Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use SafeHandle instead of IntPtr?

Tags:

I've searched the internet far and wide but didn't find a good explanation.

My question is pretty simple.

I have a DLL which has a function called Initialize and one of the parameters is a pointer that will receive a handle to be used with subsequent calls. Another parameter is a string which I will list for completeness. The signature I'm using is (in its simple form):

[DllImport(MyDll)]
static extern bool Initialize([In] string name, out IntPtr handle);

The signature in the DLL itself is written as: Initialize(LPTSTR name, HANDLE handle) with the comment "HANDLE: Pointer to a location that will receive the handle".

And subsequent calls are in the form of

[DllImport(MyDll)]
static extern bool DoSomething(IntPtr handle, uint randomParameter);

I have been reading about SafeHandle and I was wondering if I could use it to substite for my IntPtr handle. And if I can, how do I do it? Extending the abstract SafeHandle class isn't an issue, but can I directly substitute my IntPtr for SafeHandle (and use default Marshalling) or do I need to do something extra?

like image 338
Davio Avatar asked Aug 15 '12 16:08

Davio


People also ask

What is SafeHandle C#?

The SafeHandle class provides critical finalization of handle resources, preventing handles from being reclaimed prematurely by garbage collection and from being recycled by Windows to reference unintended unmanaged objects.

How do you dispose of IntPtr?

An IntPtr itself cannot be disposed, because it only represents a location in memory. Your cleanup needs to be specific to the object referred to by the IntPtr . Say you have an unmanaged function that needs a window handle to do its work. In this case you can use the property Control.

What is IntPtr C#?

The IntPtr type can be used by languages that support pointers and as a common means of referring to data between languages that do and do not support pointers. IntPtr objects can also be used to hold handles. For example, instances of IntPtr are used extensively in the System. IO.


1 Answers

You can find a more complete answer about the difference between SafeHandle and IntPtr here: IntPtr, SafeHandle and HandleRef - Explained

However, to summarize, IntPtr should be used where the argument is actually a machine-size pointer - SafeHandle should be used where the argument is actually a Win32 handle. These types are not generally interchangeable; the size of IntPtr will vary on different architectures (32 bits on x86 and 64 bits on x64 and amd64). NOTE: Under the covers I believe SafeHandle uses an IntPtr as well).

Also, unlike IntPtr, SafeHandle actually performs disposal of resources when a type is garbage collected. This ensures that system resources are not leaked when your program is running (although you should Dispose() of SafeHandle instances early when possible). Note that SafeHandle is actually abstract because there many different kinds of handles which require different approaches for proper disposal and handling.

In your specific case, you need to look at the documentation for the DLL you are calling. If it is a Win32 DLL, there may already be a SafeHandle type for it. If it's a third-party DLL, then you can roll your own SafeHandle implementation - assuming that in addition to Initialize() there is some version of Release() (or equivalent).

Some additional interesting tidbits about IntPtr vs SafeHandle can be found at:

Use SafeHandle to encapsulate native resources

SafeHandle Class Reference

SafeHandles and Critical Finalization

like image 124
LBushkin Avatar answered Oct 05 '22 18:10

LBushkin