不使用 IntPtr 的 SafeHandle
有谁知道类似于 SafeHandle 的实现,它不使用我可以从中派生的 IntPtr?或者我应该创建一个新的句柄?我需要像 DangerousGetHandle() 和 SetHandle() 这样的功能,因为这些功能在我正在使用的整个库中使用。
我问的原因是我正在编写一个使用 TAPI 2.x 的 Atapi 托管 .NET 库的应用程序(可在此处获取: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)
I追踪了一些调用,并相信问题的根源是对 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 在 32 位上只需要 4 个字节,这可能会导致问题。为了测试这个理论,我正在考虑创建一个不使用 IntPtr 的句柄。这听起来是一个合理的方法吗?
感谢您的任何建议。
Does anyone know of an implementation similar to SafeHandle that doesn’t use an IntPtr that I can derive from? Or should I create a new handle altogether? I’d need functionality like DangerousGetHandle() and SetHandle() as these are used throughout the library I'm using.
The reason I ask is that I’m writing an application that uses the Atapi managed .NET library for TAPI 2.x (available here: http://atapi.codeplex.com/ ). The application targets both 32- and 64-bit platforms, and currently works fine on 32-bit, but when running on 64-bit it throws an error on this line in the library's TapiCall class:
rc = NativeMethods.lineGetCallStatus(_hCall, pLcs);
The first lines of the exception detail:
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)
I traced back a few calls and believe the source of the problem is the following call to a native function in Tapi32.dll:
int rc = NativeMethods.lineMakeCall(Line.Handle, out hCall, address, countryCode, lpCp);
(Defined in TAPI here: http://msdn.microsoft.com/en-us/library/ms735988(VS.85).aspx )
The hCall value in 64-bit is “0” whereas in 32-bit it is a 5 digit handle. The other parameters’ values seem ok and are identical on both platforms.
My guess is that part of the problem is with the Line.Handle, which is derived from SafeHandle and is defined in the library as follows:
[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; }
}
}
The underlying handle is an IntPtr and since it's different sizes on 32- and 64-bit, I thought this might be causing a problem if TAPI is expecting just 4 bytes as on 32-bit. To test this theory out I was thinking of creating a handle that doesn’t use an IntPtr. Does this sound like a reasonable approach?
Thanks for any advice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我刚刚在 .net 3.5 上遇到了同样的问题(mscorlib 是 32 位),在这种情况下,julmar ATAPI 必须编译为 x86,因为任何 CPU 或 x64 都不是 64 位操作系统的选项。
我没有支持 mscorlib 64 位的 dotnet 4.0,因此我无法进一步调试,我唯一的选择是 x86。
有关信息,TSP 在 64 位系统上需要是 64 位版本。
I have just had the same problem on .net 3.5 (mscorlib is 32 bit) and in this case julmar ATAPI must be compiled as x86 because Any CPU or x64 is not an option for 64 bit operating systems.
I do not have dotnet 4.0 which supports mscorlib 64 bit, so I could not debug any further and my only option was x86.
For info, the TSP will need to be the 64 bit version on 64 bit systems.