66using Windows . Win32 ;
77using Windows . Win32 . Foundation ;
88using Windows . Win32 . System . Com ;
9+ using Windows . Win32 . System . WinRT ;
910
1011namespace Windows . Win32
1112{
@@ -16,8 +17,13 @@ public unsafe struct ComPtr<T> : IDisposable where T : unmanaged, IComIID
1617 {
1718 private T * _ptr ;
1819
19- public bool IsNull
20- => _ptr == null ;
20+ public readonly bool IsNull
21+ {
22+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
23+ get => _ptr is null ;
24+ }
25+
26+ // Constructors
2127
2228 public ComPtr ( T * ptr )
2329 {
@@ -27,6 +33,9 @@ public ComPtr(T* ptr)
2733 ( ( IUnknown * ) ptr ) ->AddRef ( ) ;
2834 }
2935
36+ // Methods
37+
38+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
3039 public void Attach ( T * other )
3140 {
3241 if ( _ptr is not null )
@@ -35,6 +44,14 @@ public void Attach(T* other)
3544 _ptr = other ;
3645 }
3746
47+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
48+ public T * Detach ( )
49+ {
50+ T * ptr = _ptr ;
51+ _ptr = null ;
52+ return ptr ;
53+ }
54+
3855 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
3956 public readonly T * Get ( )
4057 {
@@ -48,19 +65,62 @@ public void Attach(T* other)
4865 }
4966
5067 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
68+ [ Obsolete ( "Use `HRESULT As<U>(U** other)` instead." ) ]
5169 public readonly ComPtr < U > As < U > ( ) where U : unmanaged, IComIID
5270 {
5371 ComPtr < U > ptr = default ;
5472 ( ( IUnknown * ) _ptr ) ->QueryInterface ( ( Guid * ) Unsafe . AsPointer ( ref Unsafe . AsRef ( in U . Guid ) ) , ( void * * ) ptr . GetAddressOf ( ) ) ;
5573 return ptr ;
5674 }
5775
76+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
77+ public readonly HRESULT As < U > ( U * * other ) where U : unmanaged, IComIID
78+ {
79+ return ( ( IUnknown * ) _ptr ) ->QueryInterface ( ( Guid * ) Unsafe . AsPointer ( ref Unsafe . AsRef ( in U . Guid ) ) , ( void * * ) other ) ;
80+ }
81+
82+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
83+ public readonly HRESULT As < U > ( Guid * riid , IUnknown * * other ) where U : unmanaged, IComIID
84+ {
85+ return ( ( IUnknown * ) _ptr ) ->QueryInterface ( riid , ( void * * ) other ) ;
86+ }
87+
5888 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
5989 public readonly HRESULT CoCreateInstance ( Guid * rclsid , IUnknown * pUnkOuter = null , CLSCTX dwClsContext = CLSCTX . CLSCTX_LOCAL_SERVER )
6090 {
6191 return PInvoke . CoCreateInstance ( rclsid , pUnkOuter , dwClsContext , ( Guid * ) Unsafe . AsPointer ( ref Unsafe . AsRef ( in T . Guid ) ) , ( void * * ) this . GetAddressOf ( ) ) ;
6292 }
6393
94+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
95+ public readonly HRESULT GetAgileReference ( ref ComPtr < IAgileReference > pAgileReference )
96+ {
97+ return PInvoke . RoGetAgileReference ( AgileReferenceOptions . AGILEREFERENCE_DEFAULT , ( Guid * ) Unsafe . AsPointer ( ref Unsafe . AsRef ( in T . Guid ) ) , ( IUnknown * ) _ptr , pAgileReference . GetAddressOf ( ) ) ;
98+ }
99+
100+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
101+ public readonly HRESULT ResolveAgileReference ( ref ComPtr < IAgileReference > pAgileReference , ref ComPtr < T > other )
102+ {
103+ return pAgileReference . Get ( ) ->Resolve ( ( Guid * ) Unsafe . AsPointer ( ref Unsafe . AsRef ( in T . Guid ) ) , ( void * * ) other . GetAddressOf ( ) ) ;
104+ }
105+
106+ // Conversion operators
107+
108+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
109+ public static implicit operator ComPtr < T > ( T * other )
110+ {
111+ ComPtr < T > ptr = default ;
112+ ptr . Attach ( other ) ;
113+ return ptr ;
114+ }
115+
116+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
117+ public static implicit operator T * ( ComPtr < T > other )
118+ {
119+ return other . _ptr ;
120+ }
121+
122+ // Disposer
123+
64124 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
65125 public void Dispose ( )
66126 {
0 commit comments