hul*_*ist 3 c# pinvoke marshalling
我有以下c函数
opaque_struct* create() {}
void free(opaque_struct*) {}
Run Code Online (Sandbox Code Playgroud)
我想用PInvoke调用它:
[DllImport("test")]
public static extern IntPtr create ();
[DllImport("test")]
public static extern void free (IntPtr);
Run Code Online (Sandbox Code Playgroud)
我想这样可以正常工作,但我正在寻找一种方法,在托管代码中明确声明"free"只接受由"create"返回的IntPtr,并避免意外传递从其他函数接收的其他IntPtr.
就所有托管代码而言,指向的结构是不透明的.
即使我只是给它一个新名称,没有额外的属性,也无法扩展IntPtr.
有没有办法制作这种类型的IntPtr?
在处理非托管内存时,每个定义总是存在"意外"的可能性.
这就是说,你可以做的是换你IntPtr的一类,就像微软用自己做的SafeHandle类及相关SafeFileHandle,SafePipeHandle...等等.
您可以创建自己的SafeHandle类(可以继承System.Runtime.InteropServices.SafeHandle),并在P/Invoke声明中使用它:
[DllImport("test")]
public static extern MySafeHandle create ();
[DllImport("test")]
public static extern void free (MySafeHandle pointer);
Run Code Online (Sandbox Code Playgroud)
另一个好处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
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,甚至不需要free()手动调用,因为它在SafeHandle处理时自动完成.
| 归档时间: |
|
| 查看次数: |
1596 次 |
| 最近记录: |