如何将release/free IntPtr转为函数指针?
How to release/free IntPtr to function pointer?
我有本地 DLL(没有源代码)和两个外部方法:Init
和 DoSomeWork
。
这是我的 class-包装器:
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的正确处理呢?
你的图书馆应该/必须给你第三种方法:
void Free(IntPtr handle);
你无法知道内存是如何分配的。如果内存是通过 C malloc
分配的,你甚至不能轻易释放它。更糟糕的是,如果它是 C++ 对象,则只有 C++ 才能正确地释放它(调用正确的析构函数)。一定是库给了你释放内存的方法。
(从技术上讲,您甚至不知道 IntPtr 是什么 :-) 也许它并不是真正的指针。它可以是一个数字,你不必释放任何东西......或者它可以是 Win32 CreateFile
)
返回的 HANDLE
我有本地 DLL(没有源代码)和两个外部方法:Init
和 DoSomeWork
。
这是我的 class-包装器:
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的正确处理呢?
你的图书馆应该/必须给你第三种方法:
void Free(IntPtr handle);
你无法知道内存是如何分配的。如果内存是通过 C malloc
分配的,你甚至不能轻易释放它。更糟糕的是,如果它是 C++ 对象,则只有 C++ 才能正确地释放它(调用正确的析构函数)。一定是库给了你释放内存的方法。
(从技术上讲,您甚至不知道 IntPtr 是什么 :-) 也许它并不是真正的指针。它可以是一个数字,你不必释放任何东西......或者它可以是 Win32 CreateFile
)
HANDLE