简体   繁体   中英

Marshal an IntPtr in a typesafe manner

I have the following c functions

opaque_struct* create() {}
void free(opaque_struct*) {}

Which I want to call using PInvoke:

[DllImport("test")]
public static extern IntPtr create ();
[DllImport("test")]
public static extern void free (IntPtr);

I guess this would work fine but I'm looking for a way to in the managed code explicitly state that "free" only takes IntPtr returned by "create" and avoid accidentally passing other IntPtr received from other functions.

The struct pointed at is opaque as far as all managed code is concerned.

It is not possible to extend IntPtr even If all I do is give it a new name, no extra properties.

Is there any way to make this typed IntPtr?

When dealing with unmanaged memory, there is always the possibility of an "accident" per definition.

That said, what you could do is wrap your IntPtr in a class, just like Microsoft did with their SafeHandle class and associated SafeFileHandle , SafePipeHandle ...etc.

You could create your own SafeHandle class (you can inherit from System.Runtime.InteropServices.SafeHandle ), and use it in your P/Invoke declarations:

[DllImport("test")]
public static extern MySafeHandle create ();

[DllImport("test")]
public static extern void free (MySafeHandle pointer);

Another benefit of SafeHandle is that it implements IDisposable and thus allows the use of the using statement to ensure your free() method is always called:

using (MySafeHandle ptr = create())
{
    // Use your ptr instance here
    // You can retrieve the IntPtr value itself using
    // ptr.DangerousGetHandle()

    // When you get out of the scope of the using(), the MySafeHandle
    // object will be disposed and ptr.ReleaseHandle() will be called.
    // Just add your call to free() in the overriden ReleaseHandle method
}

As you can see, it isn't even needed to call free() manually, as it's done automatically when the SafeHandle is disposed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM