2011-10-11 3 views
1

내가 파생 할 수있는 IntPtr을 사용하지 않는 SafeHandle과 유사한 구현을 아는 사람이 있습니까? 아니면 새로운 핸들을 모두 만들어야합니까? DangerousGetHandle() 및 SetHandle()과 같은 기능이 필요합니다. 사용하는 라이브러리에서 이러한 기능이 사용됩니다.IntPtr을 사용하지 않는 SafeHandle

내가 묻는 이유는 TAPI 2.x에서 Atapi managed .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 자리 핸들입니다. 다른 매개 변수의 값은 괜찮아 보이며 두 플랫폼 모두 동일합니다.

[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입니다이며이 다르다 가입일 :

내 생각 엔 문제의 그 부분이하여 SafeHandle에서 파생 다음과 같이 라이브러리에 정의 된 Line.Handle로입니다 32 비트 및 64 비트 크기의 경우 TAPI가 32 비트에서 4 바이트 만 예상하는 경우 문제가 발생할 수 있다고 생각했습니다. 이 이론을 테스트하기 위해 IntPtr을 사용하지 않는 핸들을 작성하려고 생각했습니다. 이것은 합리적인 접근법처럼 들리니?

어떤 조언을 주셔서 감사합니다.

+1

간단한 해결책은 Atapi 라이브러리가 64 비트 IntPtr로 작동하지 않으면 32 비트 값을 보내야한다는 것입니다. 일단 값을 받으면 IntPtr로 변환하십시오. 물론 IntPtr이 SafeHandles를 수행하는 올바른 방법이기 때문에 작동하지 않는 것이 라이브러리의 버그처럼 들릴 수도 있습니다. x64 운영 체제에서도 응용 프로그램을 32 비트 응용 프로그램으로 만들면이 작업을 수행 할 수 있습니다. –

+0

잘못된 트랙에 있습니다. 운영 체제 핸들은 IntPtr입니다. SafeHandle은 그저 래퍼입니다. 핸들이 너무 빨리 해제되지 않도록하려면 ReleaseHandle() 메서드에 중단 점을 설정하십시오. 그러나 TAPI 자체가 더 가능성이 높습니다. 잘 수행되지 않았습니다. 64 비트 모드에서 사용하려고하지는 않을 것입니다. –

+0

의견에 감사드립니다. ReleaseHandle()이 너무 빨리 릴리스되지 않으며 사실 hCall 값이 0이기 때문에 오류 발생 원인 핸들 (HTCALL)은 Closed and Invalid로 표시됩니다. hCall은 Atapi에서 IntPtr로 정의됩니다. lineMakeCall 함수는 값을 할당해야합니다. 다른 해결 방법을 찾으려고 노력할 것입니다. – DeltaVax

답변

0

.net 3.5 (mscorlib는 32 비트)에서 동일한 문제가 발생했으며이 경우 julmar ATAPI는 x86으로 컴파일해야합니다. 모든 CPU 또는 x64는 64 비트 운영 체제 용 옵션이 아닙니다.

mscorlib 64 비트를 지원하는 dotnet 4.0이 없으므로 더 이상 디버깅 할 수 없으며 유일한 옵션은 x86입니다.

정보를 얻으려면 TSP가 64 비트 시스템에서 64 비트 버전이어야합니다.