有没有人知道类似于SafeHandle的实现,它不使用我可以派生的IntPtr?或者我应该创建一个新的句柄?我需要像DangerousGetHandle()和SetHandle()这样的功能,因为这些功能在我正在使用的库中使用。
我问的原因是我正在编写一个使用Atapi托管.NET库的应用程序用于TAPI 2.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)
64位的hCall值为“0”,而32位的hCall值为5位数。其他参数的值似乎正常,并且在两个平台上都是相同的。
我的猜测是问题的一部分是Line.Handle,它来自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只需要4位字节和32位一样。为了测试这个理论,我想创建一个不使用IntPtr的句柄。这听起来像是一种合理的做法吗?
感谢您的任何建议。
答案 0 :(得分:0)
我在.net 3.5上遇到了同样的问题(mscorlib是32位),在这种情况下,julmar ATAPI必须编译为x86,因为任何CPU或x64都不是64位操作系统的选项。
我没有支持mscorlib 64位的dotnet 4.0,所以我无法进一步调试,我唯一的选择是x86。
有关信息,TSP将需要是64位系统上的64位版本。
答案 1 :(得分:0)