SafeHandle, который не использует IntPtr - PullRequest
2 голосов
/ 11 октября 2011

Кто-нибудь знает о реализации, аналогичной 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)

Значение hCall в 64-битном формате равно «0», тогда как в 32-битном - это 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. Это звучит как разумный подход?

Спасибо за любой совет.

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

"Исправлено для обратных вызовов x64 с форума." https://github.com/markjulmar/atapi.net/commit/0b8fd1dcde148e7f57230915028dedebd956c65d

0 голосов
/ 13 июля 2012

У меня только что была такая же проблема на .net 3.5 (mscorlib 32-битная), и в этом случае julmar ATAPI должен быть скомпилирован как x86, потому что любой 64-битный процессор или x64 не подходит для 64-битных операционных систем.

У меня нет dotnet 4.0, который поддерживает 64-битную версию mscorlib, поэтому я больше не мог отлаживать, и мой единственный вариант был x86.

Для информации, TSP должен быть 64-битной версией в 64-битных системах.

...