ProteoWizard
pinned_gcroot.h
Go to the documentation of this file.
1//
2// $Id$
3//
4//
5// Original author: Matt Chambers <matt.chambers .@. vanderbilt.edu>
6//
7// Copyright (c) Microsoft Corporation. All rights reserved.
8//
9// Slightly modified version of gcroot.h that pins the GCHandle and allows access to the handle.
10//
11
12#pragma once
13#include <gcroot.h>
14
15#ifdef __cplusplus_cli
16#define __GCHANDLE_TO_VOIDPTR(x) ((GCHandle::operator System::IntPtr(x)).ToPointer())
17#define __VOIDPTR_TO_GCHANDLE(x) (GCHandle::operator GCHandle(System::IntPtr(x)))
18#define __NULLPTR nullptr
19#else /* __cplusplus_cli */
20#define __GCHANDLE_TO_VOIDPTR(x) ((GCHandle::op_Explicit(x)).ToPointer())
21#define __VOIDPTR_TO_GCHANDLE(x) (GCHandle::op_Explicit(x))
22#define __NULLPTR 0
23#endif /* __cplusplus_cli */
24
25#ifndef __DEFINE_GCROOT_IN_GLOBAL_NAMESPACE
26namespace msclr
27{
28#endif /* __DEFINE_GCROOT_IN_GLOBAL_NAMESPACE */
29
30 /// pinned_gcroot: a slightly modified gcroot that pins its GCHandle
31 template <class T> struct pinned_gcroot {
32
33 typedef System::Runtime::InteropServices::GCHandle GCHandle;
34 typedef System::Runtime::InteropServices::GCHandleType GCHandleType;
35
36 // always allocate a new handle during construction (see above)
37 //
38 // Initializes to a NULL handle, which is always safe
39 [System::Diagnostics::DebuggerStepThroughAttribute]
40 [System::Security::SecuritySafeCritical]
42 _handle = __GCHANDLE_TO_VOIDPTR(GCHandle::Alloc(__NULLPTR, GCHandleType::Pinned));
43 }
44
45 // this can't be T& here because & does not yet work on managed types
46 // (T should be a pointer anyway).
47 //
49 _handle = __GCHANDLE_TO_VOIDPTR(GCHandle::Alloc(t, GCHandleType::Pinned));
50 }
51
53 // don't copy a handle, copy what it points to (see above)
55 GCHandle::Alloc(
56 __VOIDPTR_TO_GCHANDLE(r._handle).Target, GCHandleType::Pinned));
57 }
58
59 // Since C++ objects and handles are allocated 1-to-1, we can
60 // free the handle when the object is destroyed
61 //
62 [System::Diagnostics::DebuggerStepThroughAttribute]
63 [System::Security::SecurityCritical]
66 g.Free();
67 _handle = 0; // should fail if reconstituted
68 }
69
70 [System::Diagnostics::DebuggerStepThroughAttribute]
71 [System::Security::SecurityCritical]
73 // no need to check for valid handle; was allocated in ctor
75 return *this;
76 }
77
79 // no need to check for valid handle; was allocated in ctor
80 T t = (T)r;
82 return *this;
83 }
84
85 void swap(pinned_gcroot<T> & _right)
86 {
87 using std::swap;
88 swap(_handle, _right._handle);
89 }
90
91 // The managed object is not a secret or protected resource, so it's okay to expose to anyone who has access to the gcroot object
92 [System::Security::SecuritySafeCritical]
93 operator T () const {
94 // gcroot is typesafe, so use static_cast
95 return static_cast<T>(__VOIDPTR_TO_GCHANDLE(_handle).Target);
96 }
97
98 // don't return T& here because & to gc pointer not yet implemented
99 // (T should be a pointer anyway).
100 [System::Security::SecuritySafeCritical]
101 T operator->() const {
102 // gcroot is typesafe, so use static_cast
103 return static_cast<T>(__VOIDPTR_TO_GCHANDLE(_handle).Target);
104 }
105
106 System::IntPtr operator& () const {
107 return __VOIDPTR_TO_GCHANDLE(_handle).AddrOfPinnedObject();
108 }
109
110 void* handle() const {
111 return _handle;
112 }
113
114 private:
115 // Don't let anyone copy the handle value directly, or make a copy
116 // by taking the address of this object and pointing to it from
117 // somewhere else. The root will be freed when the dtor of this
118 // object gets called, and anyone pointing to it still will
119 // cause serious harm to the Garbage Collector.
120 //
121 void* _handle;
122 };
123
124 template<typename T>
125 void swap(pinned_gcroot<T> & _left,
126 pinned_gcroot<T> & _right)
127 {
128 _left.swap(_right);
129 }
130
131#ifndef __DEFINE_GCROOT_IN_GLOBAL_NAMESPACE
132} // namespace msclr
133#endif /* __DEFINE_GCROOT_IN_GLOBAL_NAMESPACE */
134
135#undef __GCHANDLE_TO_VOIDPTR
136#undef __VOIDPTR_TO_GCHANDLE
137#undef __NULLPTR
138
139
void swap(pwiz::util::BinaryData< T > &lhs, std::vector< T > &rhs)
#define __VOIDPTR_TO_GCHANDLE(x)
#define __GCHANDLE_TO_VOIDPTR(x)
#define __NULLPTR
pinned_gcroot: a slightly modified gcroot that pins its GCHandle
pinned_gcroot & operator=(T t)
System::Runtime::InteropServices::GCHandle GCHandle
System::Runtime::InteropServices::GCHandleType GCHandleType
System::IntPtr operator&() const
void swap(pinned_gcroot< T > &_right)
pinned_gcroot & operator=(const pinned_gcroot &r)
pinned_gcroot(const pinned_gcroot &r)
void * handle() const