JulMar 的 ATAPI 中的 LineMakeCall 抛出 ObjectDisposedException
LineMakeCall in JulMar's ATAPI throws ObjectDisposedException
我目前正在使用 JulMar's ATAPI 与 Microsoft 的 Telephony 交互 API (TAPI) 2.x.
每当我尝试向指定线路或地址发出呼叫时,我都会收到 ObjectDispoedException。我认为会抛出此异常,因为 LineMakeCall-Function 从未设置 HCALL 句柄。
DLLI导入:
[DllImport("Tapi32.dll", EntryPoint = "lineMakeCallW", CharSet = CharSet.Auto)]
internal static extern int lineMakeCall(HTLINE hLine, out uint hCall, string DestAddress, int CountryCode, IntPtr lpCallParams);
函数调用:
uint hCall = 0;
int rc = NativeMethods.lineMakeCall(Line.Handle, out hCall, address, countryCode, lpCp);
现在,问题是当此方法终止时,hCall 未设置,我不明白为什么。但是,当我将目标框架更改为 .NET 4 或更高版本时(默认情况下我是 运行 我在 .NET 3.5 上的应用程序),将设置 hCall。
据我了解,必须在函数终止之前设置 out 参数。
我阅读了 .NET 3.5 和 .NET 4 之间的区别,但没有找到对我的情况有用的内容。
有人知道为什么没有设置 out 参数吗?
编辑:
我终于成功了,想分享这个解决方案。我基本上按照 Kris Vanherck
的建议做了
Try changing your signature of out uint hCall into ref IntPtr lphCall
DLLI导入:
[DllImport("Tapi32.dll", EntryPoint = "lineMakeCallW", CharSet = CharSet.Auto)]
internal static extern int lineMakeCall(HTLINE hLine, IntPtr hCall, string DestAddress, int CountryCode, IntPtr lpCallParams);
函数调用:
public TapiCall MakeCall(string address, int countryCode, MakeCallParams param)
{
if (!Line.IsOpen)
throw new TapiException("Line is not open", NativeMethods.LINEERR_OPERATIONUNAVAIL);
IntPtr lpCp = IntPtr.Zero;
//jf 2016-10-07
IntPtr lpHcall = IntPtr.Zero;
//jf
try
{
lpCp = MakeCallParams.ProcessCallParams(_addressId, param, 0);
//jf 2016-10-16
CallHandle callHandle = new CallHandle();
lpHcall = Marshal.AllocHGlobal(Marshal.SizeOf(callHandle));
Marshal.StructureToPtr(callHandle, lpHcall, true);
//jf
int rc = NativeMethods.lineMakeCall(Line.Handle, lpHcall, address, countryCode, lpCp);
if (rc < 0)
throw new TapiException("lineMakeCall failed", rc);
else
{
// Wait for the LINE_REPLY so we don't need to deal with the value type
// issues of IntPtr being filled in async.
var req = new PendingTapiRequest(rc, null, null);
Line.TapiManager.AddAsyncRequest(req);
req.AsyncWaitHandle.WaitOne();
if (req.Result < 0)
throw new TapiException("lineMakeCall failed", req.Result);
//jf 2016-10-07
Marshal.PtrToStructure(lpHcall, callHandle);
//jf
var call = new TapiCall(this, callHandle.hCall);
AddCall(call);
return call;
}
}
finally
{
//jf 2016-10-07
if(lpHcall != IntPtr.Zero)
Marshal.FreeHGlobal(lpHcall);
//jf
if (lpCp != IntPtr.Zero)
Marshal.FreeHGlobal(lpCp);
}
}
最后是 CallHandle class:
[StructLayout(LayoutKind.Sequential)]
internal class CallHandle
{
internal uint hCall;
}
如果您查看函数的 MSDN page,您可以注意到以下部分:
The handle is only valid after the LINE_REPLY message is received by the application indicating that the lineMakeCall function successfully completed.
所以不能保证在函数调用结束前设置。它实际上也不是句柄。从命名上可以看出:"lp"代表长指针,"h"代表句柄。
'lphCall' 是指向内存位置的指针,当 LINE_REPLY 返回时(可能在函数 returns 之前、期间或之后)将设置句柄。
这是一个时间问题,改变框架可能只是做了一些事情slower/faster,给你不同的结果。
尝试将 out uint hCall
的签名更改为 ref IntPtr lphCall
尝试以下步骤:
- 重新启动 Windows 电话服务。在某些情况下,问题是 ATAPI 是 Win32 TAPI dll 上的包装器,它可以是 unloaded/reloaded 在 stopping/rebooting Windows 电话服务
之后
- ATAPI 位版本必须与您的操作系统版本相同。请确保您在 64 位环境中使用 64 位 ATAPI 版本Windows,在 32 位环境中使用 32 位 ATAPI。
我目前正在使用 JulMar's ATAPI 与 Microsoft 的 Telephony 交互 API (TAPI) 2.x.
每当我尝试向指定线路或地址发出呼叫时,我都会收到 ObjectDispoedException。我认为会抛出此异常,因为 LineMakeCall-Function 从未设置 HCALL 句柄。
DLLI导入:
[DllImport("Tapi32.dll", EntryPoint = "lineMakeCallW", CharSet = CharSet.Auto)]
internal static extern int lineMakeCall(HTLINE hLine, out uint hCall, string DestAddress, int CountryCode, IntPtr lpCallParams);
函数调用:
uint hCall = 0;
int rc = NativeMethods.lineMakeCall(Line.Handle, out hCall, address, countryCode, lpCp);
现在,问题是当此方法终止时,hCall 未设置,我不明白为什么。但是,当我将目标框架更改为 .NET 4 或更高版本时(默认情况下我是 运行 我在 .NET 3.5 上的应用程序),将设置 hCall。
据我了解,必须在函数终止之前设置 out 参数。
我阅读了 .NET 3.5 和 .NET 4 之间的区别,但没有找到对我的情况有用的内容。
有人知道为什么没有设置 out 参数吗?
编辑:
我终于成功了,想分享这个解决方案。我基本上按照 Kris Vanherck
的建议做了Try changing your signature of out uint hCall into ref IntPtr lphCall
DLLI导入:
[DllImport("Tapi32.dll", EntryPoint = "lineMakeCallW", CharSet = CharSet.Auto)]
internal static extern int lineMakeCall(HTLINE hLine, IntPtr hCall, string DestAddress, int CountryCode, IntPtr lpCallParams);
函数调用:
public TapiCall MakeCall(string address, int countryCode, MakeCallParams param)
{
if (!Line.IsOpen)
throw new TapiException("Line is not open", NativeMethods.LINEERR_OPERATIONUNAVAIL);
IntPtr lpCp = IntPtr.Zero;
//jf 2016-10-07
IntPtr lpHcall = IntPtr.Zero;
//jf
try
{
lpCp = MakeCallParams.ProcessCallParams(_addressId, param, 0);
//jf 2016-10-16
CallHandle callHandle = new CallHandle();
lpHcall = Marshal.AllocHGlobal(Marshal.SizeOf(callHandle));
Marshal.StructureToPtr(callHandle, lpHcall, true);
//jf
int rc = NativeMethods.lineMakeCall(Line.Handle, lpHcall, address, countryCode, lpCp);
if (rc < 0)
throw new TapiException("lineMakeCall failed", rc);
else
{
// Wait for the LINE_REPLY so we don't need to deal with the value type
// issues of IntPtr being filled in async.
var req = new PendingTapiRequest(rc, null, null);
Line.TapiManager.AddAsyncRequest(req);
req.AsyncWaitHandle.WaitOne();
if (req.Result < 0)
throw new TapiException("lineMakeCall failed", req.Result);
//jf 2016-10-07
Marshal.PtrToStructure(lpHcall, callHandle);
//jf
var call = new TapiCall(this, callHandle.hCall);
AddCall(call);
return call;
}
}
finally
{
//jf 2016-10-07
if(lpHcall != IntPtr.Zero)
Marshal.FreeHGlobal(lpHcall);
//jf
if (lpCp != IntPtr.Zero)
Marshal.FreeHGlobal(lpCp);
}
}
最后是 CallHandle class:
[StructLayout(LayoutKind.Sequential)]
internal class CallHandle
{
internal uint hCall;
}
如果您查看函数的 MSDN page,您可以注意到以下部分:
The handle is only valid after the LINE_REPLY message is received by the application indicating that the lineMakeCall function successfully completed.
所以不能保证在函数调用结束前设置。它实际上也不是句柄。从命名上可以看出:"lp"代表长指针,"h"代表句柄。 'lphCall' 是指向内存位置的指针,当 LINE_REPLY 返回时(可能在函数 returns 之前、期间或之后)将设置句柄。
这是一个时间问题,改变框架可能只是做了一些事情slower/faster,给你不同的结果。
尝试将 out uint hCall
的签名更改为 ref IntPtr lphCall
尝试以下步骤:
- 重新启动 Windows 电话服务。在某些情况下,问题是 ATAPI 是 Win32 TAPI dll 上的包装器,它可以是 unloaded/reloaded 在 stopping/rebooting Windows 电话服务 之后
- ATAPI 位版本必须与您的操作系统版本相同。请确保您在 64 位环境中使用 64 位 ATAPI 版本Windows,在 32 位环境中使用 32 位 ATAPI。