2011-12-03 1 views
8

는 희망이 서명 SO 너무 모호한 아니라, 호출/다음 P를 고려하십시오특정 경우에 널 포인터가 필요한 P/Invoke 서명에서 SafeHandle을 어떻게 사용할 수 있습니까?

[DllImport("odbc32.dll", CharSet = CharSet.Unicode)] 
internal static extern OdbcResult SQLAllocHandle(
    OdbcHandleType HandleType, 
    IntPtr InputHandle, 
    ref IntPtr OutputHandlePtr); 

나는 다음과 같이 SafeHandles을 사용하려면이 서명을 재 설계하고 싶습니다 :

[DllImport("odbc32.dll", CharSet = CharSet.Unicode)] 
internal static extern OdbcResult SQLAllocHandle(
    OdbcHandleType HandleType, 
    MySafeHandle InputHandle, 
    ref MySafeHandle OutputHandlePtr); 

그러나 according to MSDN이면 InputHandle 인수는 HandleType 인수가 SQL_HANDLE_ENV이면 널 포인터 여야하고 그렇지 않으면 널이 아닌 포인터 여야합니다.

단일 P/Invoke 서명으로 어떻게 이러한 의미를 캡처합니까? 답안에 전화 사이트 예제를 포함하십시오. 나의 현재 해결책은 두 개의 서명을 사용하는 것이다.

답변

4

SafeHandle은 실제 SafeHandle이 아닌 null을 전달해야하는 클래스입니다. null 참조는 P/Invoke에서 널 포인터로 마샬링됩니다.

SafeHandle handle = new SafeHandle(); 
OdbcResult result= SQLAllocHandle(OdbcHandleType.SQL_HANDLE_ENV, null, ref handle); 
+2

'out SafeHandle' 매개 변수를 선언 할 수도 있습니다. –

+5

여기서는 작동하지 않습니다. System.StubHelpers.StubHelpers.SafeHandleAddRef (SafeHandle pHandle, Boolean & success)에서 ArgumentNullException을 얻었습니다. – ordag

+0

예, @ shf301, P/Invoke 호출에서 작동하지 않습니다. 너도 해봤 니? – jnm2

1

The answer by shf301 입력 인수 InputHandle위한 null 통과한다. 이것은 대부분의 API에서 작동하지 않습니다 (어쩌면 OP의 특정 문제에 대해 답을 받아 들였을 것입니다).

[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] 
public class RegionHandle : SafeHandleZeroOrMinusOneIsInvalid 
{ 
    private RegionHandle() : base(true) {} 

    public static readonly RegionHandle Null = new RegionHandle(); 

    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
    override protected bool ReleaseHandle() 
    { 
     return Region.DeleteObject(handle); 
    } 
} 

그것은 내가 널 핸들을 전달하기 위해이 작업을 수행 할 수 있다는 것을 의미합니다 :

SomeApi(RegionHandle.Null); 

그것은이 IntPtr.Zero 정적 멤버가 얼마나 비슷

나는이 패턴을 사용합니다.

관련 문제