不使用IntPtr的SafeHandle

本文关键字:SafeHandle IntPtr | 更新日期: 2023-09-27 18:10:51

是否有人知道类似于SafeHandle的实现,不使用我可以从中派生的IntPtr ?或者我应该创建一个新的句柄?我需要像DangerousGetHandle()和SetHandle()这样的功能,因为它们在我使用的整个库中使用。

我问的原因是我正在为TAPI 2编写一个使用Atapi管理的。net库的应用程序。X(可在这里获得:http://atapi.codeplex.com/)。该应用程序针对32位和64位平台,目前在32位平台上运行良好,但在64位平台上运行时,它会在库的TapiCall类的这一行抛出一个错误:

rc = NativeMethods.lineGetCallStatus(_hCall, pLcs);

异常详细信息的第一行:

System.ObjectDisposedException was unhandled
Message=Safe handle has been closed
Source=mscorlib
ObjectName=""
StackTrace:
at System.StubHelpers.StubHelpers.SafeHandleC2NHelper(Object pThis, IntPtr pCleanupWorkList)
at JulMar.Atapi.Interop.NativeMethods.lineGetCallStatus(HTCALL hCall, IntPtr lpCallStatus)

我跟踪了几个调用,并认为问题的根源是对Tapi32.dll中的本机函数的以下调用:

int rc = NativeMethods.lineMakeCall(Line.Handle, out hCall, address, countryCode, lpCp);

(在TAPI中定义:http://msdn.microsoft.com/en-us/library/ms735988(VS.85).aspx)

hCall值在64位是"0",而在32位是5位句柄。其他参数的值似乎没有问题,并且在两个平台上是相同的。

我猜部分问题出在线路上。句柄,派生自SafeHandle,在库中定义如下:

[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
internal class HTLINE : SafeHandle
{
    internal HTLINE()
        : base(IntPtr.Zero, true)
    {
    }
    internal HTLINE(IntPtr preexistingHandle, bool ownsHandle)
        : base(preexistingHandle, ownsHandle)
    {
    }
    protected override bool ReleaseHandle()
    {
        if (handle != IntPtr.Zero)
        {
            NativeMethods.lineClose(handle);
            handle = IntPtr.Zero;
        }
        return true;
    }
    public override bool IsInvalid
    {
        get { return handle == IntPtr.Zero; }
    }
}

底层句柄是一个IntPtr,因为它在32位和64位上的大小不同,我认为这可能会导致一个问题,如果TAPI期望32位上只有4个字节。为了测试这个理论,我正在考虑创建一个不使用IntPtr的句柄。这听起来像是一个合理的方法吗?

谢谢你的建议

不使用IntPtr的SafeHandle

我刚刚在。net 3.5 (mscorlib是32位)上遇到了同样的问题,在这种情况下,julmar ATAPI必须编译为x86,因为任何CPU或x64都不是64位操作系统的选项。

我没有支持mscorlib 64位的dotnet 4.0,所以我无法进一步调试,我唯一的选择是x86。

对于信息,TSP需要是64位系统上的64位版本。