2

私が派生できる IntPtr を使用しない SafeHandle に似た実装を知っている人はいますか? それとも、まったく新しいハンドルを作成する必要がありますか? 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)

いくつかの呼び出しを追跡したところ、問題の原因は 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 ビットでは 5 桁のハンドルです。他のパラメータの値は問題ないようで、両方のプラットフォームで同じです。

私の推測では、問題の一部は、SafeHandle から派生し、ライブラリで次のように定義されている Line.Handle にあると考えられます。

[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 を使用しないハンドルを作成することを考えていました。これは合理的なアプローチのように聞こえますか?

アドバイスをありがとう。

4

2 に答える 2

0

.net 3.5 (mscorlib は 32 ビット) で同じ問題が発生しました。この場合、Julmar ATAPI を x86 としてコンパイルする必要があります。これは、任意の CPU または x64 が 64 ビット オペレーティング システムのオプションではないためです。

mscorlib 64 ビットをサポートする dotnet 4.0 がないため、これ以上デバッグできず、唯一のオプションは x86 でした。

参考までに、TSP は 64 ビット システムでは 64 ビット バージョンである必要があります。

于 2012-07-13T07:49:35.967 に答える