2016-09-20 34 views
0

В настоящее время я использую JulMar's ATAPI для взаимодействия с API телефонии Microsoft (TAPI) 2.x.LineMakeCall в ATAPI JulMar выбрасывает ObjectDisposedException

Всякий раз, когда я пытаюсь поместить вызов на указанную строку или адрес, я получаю исключение ObjectDispoedException. Я думаю, что это исключение выбрано, потому что LineMakeCall-Function никогда не устанавливает ручку HCALL.

DllImport:

[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 не задан?

Edit:

я, наконец, удалось получить его работу и хотите поделиться этим решением. Я в основном сделал то, что было рекомендовано Kris Vanherck

Попробуйте изменить подпись из UINT hCall в исх IntPtr lphCall

DllImport:

[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:

[StructLayout(LayoutKind.Sequential)] 
internal class CallHandle 
{ 
    internal uint hCall; 
} 

ответ

0

Try следующие шаги:

  • перезапуска Telephony службы Windows. В некоторых случаях проблема заключается в том, что ATAPI является оболочкой на dll Win32 TAPI, которая может быть выгружена/перезагружена после остановки/перезагрузки службы телефонии Windows.
  • Битовая версия ATAPI должна быть такой же, как версия операционной системы. Убедитесь, что вы используете 64-разрядную версию ATAPI в 64-разрядной среде Windows и 32-разрядную ATAPI в 32-разрядной среде.
0

Если вы посмотрите на MSDN page для функции вы можете отметить этот раздел:

Ручка действительна только после того, как сообщение LINE_REPLY получено приложением, указывающее, что функция lineMakeCall успешно завершена.

Таким образом, это не гарантируется быть установленным до конца вызова функции. И на самом деле это не ручка. Вы можете увидеть это в именовании: «lp» означает длинный указатель и «h» для дескриптора. 'lphCall' - указатель на ячейку памяти, где дескриптор будет установлен, когда возвращается LINE_REPLY (что может быть до, во время или после возвращения функции).

Это временная проблема, изменение рамки может просто сделать некоторые вещи медленнее/быстрее, давая вам другой результат.

Попробуйте изменить подпись out uint hCall в ref IntPtr lphCall

+0

Спасибо за ваш ответ, но это не помогло. lphCall по-прежнему не устанавливается. – Oerk