簡體   English   中英

以類型安全的方式制定IntPtr

[英]Marshal an IntPtr in a typesafe manner

我有以下c函數

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

我想用PInvoke調用它:

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

我想這樣可以正常工作,但我正在尋找一種方法,在托管代碼中明確聲明“free”只接受由“create”返回的IntPtr,並避免意外傳遞從其他函數接收的其他IntPtr。

就所有托管代碼而言,指向的結構是不透明的。

即使我只是給它一個新名稱,沒有額外的屬性,也無法擴展IntPtr。

有沒有辦法制作這種類型的IntPtr?

處理非托管內存時,每個定義總會出現“意外”的可能性。

也就是說,你可以做的就是將你的IntPtr包裝在一個類中,就像微軟用他們的SafeHandle類和相關的SafeFileHandleSafePipeHandle等一樣。

您可以創建自己的SafeHandle類(可以從System.Runtime.InteropServices.SafeHandle繼承),並在P / Invoke聲明中使用它:

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

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

SafeHandle另一個好處是它實現了IDisposable ,因此允許使用using語句來確保始終調用free()方法:

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
}

正如您所看到的,甚至不需要手動調用free() ,因為它是在處理SafeHandle時自動完成的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM