【发布时间】:2015-03-16 13:05:13
【问题描述】:
我有本机 DLL(无源),有两种外部方法:Init 和 DoSomeWork。
这是我的类包装器:
public class MyClass : IDisposable
{
[DllImport(@"myDLL.dll",
SetLastError = true,
CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi,
EntryPoint = "EntryPoint#1",
ExactSpelling = true)]
private static extern IntPtr InitNative();
[DllImport(@"myDLL.dll",
SetLastError = true,
CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi,
EntryPoint = "EntryPoint#2",
ExactSpelling = true)]
private static extern ushort DoSomeWorkN(byte[] arrayOut, [In] IntPtr initHandle);
private readonly IntPtr _initHandle;
public MyClass()
{
_initHandle = InitNative();
}
protected override byte[] DoSomeWork()
{
...
DoSomeWorkN(buffOut, _initHandle);
...
}
public override void Dispose()
{
//???
}
我试过了:
Marshal.FreeHGlobal(_initHandle); //throws exception: Invalid access to memory location. (Exception from HRESULT: 0x800703E6)"}
Marshal.FreeCoTaskMem(_initHandle); //throws Access violation exception
Marshal.FreeBSTR(_initHandle); //doesn't throw exception, but doesn't work (after calling that method IntPtr isn't IntPtr.Zero)
那么,如何实现对_initHandle的正确处理呢?
【问题讨论】:
-
我们怎么知道,这是你的大秘密图书馆。
-
将本地的东西拉到托管端似乎有点奇怪......只是将它传递回本地端。
-
@SwDevMan81 不,这是一种常见模式...假设您使用 CreateFile Win32 api...它返回打开文件的句柄...您使用 WriteFile 写入它(使用句柄),然后 CloseHandle 将其关闭。一般来说,如果你可以想象这个库不仅仅由静态方法组成,那么
this必须保存在某个地方:-) -
@xanatos 当然,您可以将该句柄包装在托管对象中,例如
SafeFileHandle在您的示例中。当然,您需要指定谁是该句柄的所有者——它可能是您的代码,也可能是库的。 -
@Luaan 我不明白您的评论与我的评论有何关联。我在评论
Also seems a bit strange to pull something native to the managed side... only to pass it back to the native side。如何以安全的方式处理非托管句柄是我们不谈论的事情
标签: c# native release free intptr