1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4//
5// File: CustomMarshalerInfo.h
6//
7
8//
9// Custom marshaler information used when marshaling
10// a parameter with a custom marshaler.
11//
12
13
14#ifndef _CUSTOMMARSHALERINFO_H_
15#define _CUSTOMMARSHALERINFO_H_
16
17
18#include "vars.hpp"
19#include "slist.h"
20
21
22// This enumeration is used to retrieve a method desc from CustomMarshalerInfo::GetCustomMarshalerMD().
23enum EnumCustomMarshalerMethods
24{
25 CustomMarshalerMethods_MarshalNativeToManaged = 0,
26 CustomMarshalerMethods_MarshalManagedToNative,
27 CustomMarshalerMethods_CleanUpNativeData,
28 CustomMarshalerMethods_CleanUpManagedData,
29 CustomMarshalerMethods_GetNativeDataSize,
30 CustomMarshalerMethods_GetInstance,
31 CustomMarshalerMethods_LastMember
32};
33
34
35class CustomMarshalerInfo
36{
37public:
38 // Constructor and destructor.
39 CustomMarshalerInfo(BaseDomain* pDomain, TypeHandle hndCustomMarshalerType, TypeHandle hndManagedType, LPCUTF8 strCookie, DWORD cCookieStrBytes);
40 ~CustomMarshalerInfo();
41
42 // CustomMarshalerInfo's are always allocated on the loader heap so we need to redefine
43 // the new and delete operators to ensure this.
44 void* operator new(size_t size, LoaderHeap* pHeap);
45 void operator delete(void* pMem);
46
47 // Helpers used to invoke the different methods in the ICustomMarshaler interface.
48 OBJECTREF InvokeMarshalNativeToManagedMeth(void* pNative);
49 void* InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj);
50 void InvokeCleanUpNativeMeth(void* pNative);
51 void InvokeCleanUpManagedMeth(OBJECTREF MngObj);
52
53 // Accessors.
54 int GetNativeSize()
55 {
56 LIMITED_METHOD_CONTRACT;
57 return m_NativeSize;
58 }
59
60 int GetManagedSize()
61 {
62 WRAPPER_NO_CONTRACT;
63 return m_hndManagedType.GetSize();
64 }
65
66 TypeHandle GetManagedType()
67 {
68 LIMITED_METHOD_CONTRACT;
69 return m_hndManagedType;
70 }
71
72 BOOL IsDataByValue()
73 {
74 LIMITED_METHOD_CONTRACT;
75 return m_bDataIsByValue;
76 }
77
78 OBJECTHANDLE GetCustomMarshaler()
79 {
80 LIMITED_METHOD_CONTRACT;
81 return m_hndCustomMarshaler;
82 }
83
84 TypeHandle GetCustomMarshalerType()
85 {
86 CONTRACTL
87 {
88 NOTHROW;
89 GC_NOTRIGGER;
90 SO_TOLERANT;
91 MODE_COOPERATIVE;
92 }
93 CONTRACTL_END;
94 return ObjectFromHandle(m_hndCustomMarshaler)->GetTypeHandle();
95 }
96
97 // Helper function to retrieve a custom marshaler method desc.
98 static MethodDesc* GetCustomMarshalerMD(EnumCustomMarshalerMethods Method, TypeHandle hndCustomMarshalertype);
99
100 // Link used to contain this CM info in a linked list.
101 SLink m_Link;
102
103private:
104 int m_NativeSize;
105 TypeHandle m_hndManagedType;
106 OBJECTHANDLE m_hndCustomMarshaler;
107 MethodDesc* m_pMarshalNativeToManagedMD;
108 MethodDesc* m_pMarshalManagedToNativeMD;
109 MethodDesc* m_pCleanUpNativeDataMD;
110 MethodDesc* m_pCleanUpManagedDataMD;
111 BOOL m_bDataIsByValue;
112};
113
114
115typedef SList<CustomMarshalerInfo, true> CMINFOLIST;
116
117
118class EECMHelperHashtableKey
119{
120public:
121 EECMHelperHashtableKey(DWORD cMarshalerTypeNameBytes, LPCSTR strMarshalerTypeName, DWORD cCookieStrBytes, LPCSTR strCookie, Instantiation instantiation)
122 : m_cMarshalerTypeNameBytes(cMarshalerTypeNameBytes)
123 , m_strMarshalerTypeName(strMarshalerTypeName)
124 , m_cCookieStrBytes(cCookieStrBytes)
125 , m_strCookie(strCookie)
126 , m_Instantiation(instantiation)
127 {
128 LIMITED_METHOD_CONTRACT;
129 }
130
131 inline DWORD GetMarshalerTypeNameByteCount() const
132 {
133 LIMITED_METHOD_CONTRACT;
134 return m_cMarshalerTypeNameBytes;
135 }
136 inline LPCSTR GetMarshalerTypeName() const
137 {
138 LIMITED_METHOD_CONTRACT;
139 return m_strMarshalerTypeName;
140 }
141 inline LPCSTR GetCookieString() const
142 {
143 LIMITED_METHOD_CONTRACT;
144 return m_strCookie;
145 }
146 inline ULONG GetCookieStringByteCount() const
147 {
148 LIMITED_METHOD_CONTRACT;
149 return m_cCookieStrBytes;
150 }
151 inline Instantiation GetMarshalerInstantiation() const
152 {
153 LIMITED_METHOD_CONTRACT;
154 return m_Instantiation;
155 }
156
157 DWORD m_cMarshalerTypeNameBytes;
158 LPCSTR m_strMarshalerTypeName;
159 DWORD m_cCookieStrBytes;
160 LPCSTR m_strCookie;
161 Instantiation m_Instantiation;
162};
163
164
165class EECMHelperHashtableHelper
166{
167public:
168 static EEHashEntry_t* AllocateEntry(EECMHelperHashtableKey* pKey, BOOL bDeepCopy, AllocationHeap Heap);
169 static void DeleteEntry(EEHashEntry_t* pEntry, AllocationHeap Heap);
170 static BOOL CompareKeys(EEHashEntry_t* pEntry, EECMHelperHashtableKey* pKey);
171 static DWORD Hash(EECMHelperHashtableKey* pKey);
172};
173
174
175typedef EEHashTable<EECMHelperHashtableKey*, EECMHelperHashtableHelper, TRUE> EECMHelperHashTable;
176
177
178class CustomMarshalerHelper
179{
180public:
181 // Helpers used to invoke the different methods in the ICustomMarshaler interface.
182 OBJECTREF InvokeMarshalNativeToManagedMeth(void* pNative);
183 void* InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj);
184 void InvokeCleanUpNativeMeth(void* pNative);
185 void InvokeCleanUpManagedMeth(OBJECTREF MngObj);
186
187 // Accessors.
188 int GetNativeSize()
189 {
190 WRAPPER_NO_CONTRACT;
191 return GetCustomMarshalerInfo()->GetNativeSize();
192 }
193
194 int GetManagedSize()
195 {
196 WRAPPER_NO_CONTRACT;
197 return GetCustomMarshalerInfo()->GetManagedSize();
198 }
199
200 TypeHandle GetManagedType()
201 {
202 WRAPPER_NO_CONTRACT;
203 return GetCustomMarshalerInfo()->GetManagedType();
204 }
205
206 BOOL IsDataByValue()
207 {
208 WRAPPER_NO_CONTRACT;
209 return GetCustomMarshalerInfo()->IsDataByValue();
210 }
211
212 // Helper function to retrieve the custom marshaler object.
213 virtual CustomMarshalerInfo* GetCustomMarshalerInfo() = 0;
214
215protected:
216 ~CustomMarshalerHelper( void )
217 {
218 LIMITED_METHOD_CONTRACT;
219 }
220};
221
222
223class NonSharedCustomMarshalerHelper : public CustomMarshalerHelper
224{
225public:
226 // Constructor.
227 NonSharedCustomMarshalerHelper(CustomMarshalerInfo* pCMInfo) : m_pCMInfo(pCMInfo)
228 {
229 WRAPPER_NO_CONTRACT;
230 }
231
232 // CustomMarshalerHelpers's are always allocated on the loader heap so we need to redefine
233 // the new and delete operators to ensure this.
234 void *operator new(size_t size, LoaderHeap *pHeap);
235 void operator delete(void* pMem);
236
237protected:
238 // Helper function to retrieve the custom marshaler object.
239 virtual CustomMarshalerInfo* GetCustomMarshalerInfo()
240 {
241 LIMITED_METHOD_CONTRACT;
242 return m_pCMInfo;
243 }
244
245private:
246 CustomMarshalerInfo* m_pCMInfo;
247};
248
249
250class SharedCustomMarshalerHelper : public CustomMarshalerHelper
251{
252public:
253 // Constructor.
254 SharedCustomMarshalerHelper(Assembly* pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes);
255
256 // CustomMarshalerHelpers's are always allocated on the loader heap so we need to redefine
257 // the new and delete operators to ensure this.
258 void* operator new(size_t size, LoaderHeap* pHeap);
259 void operator delete(void* pMem);
260
261 // Accessors.
262 inline Assembly* GetAssembly()
263 {
264 LIMITED_METHOD_CONTRACT;
265 return m_pAssembly;
266 }
267
268 inline TypeHandle GetManagedType()
269 {
270 LIMITED_METHOD_CONTRACT;
271 return m_hndManagedType;
272 }
273
274 inline DWORD GetMarshalerTypeNameByteCount()
275 {
276 LIMITED_METHOD_CONTRACT;
277 return m_cMarshalerTypeNameBytes;
278 }
279
280 inline LPCSTR GetMarshalerTypeName()
281 {
282 LIMITED_METHOD_CONTRACT;
283 return m_strMarshalerTypeName;
284 }
285
286 inline LPCSTR GetCookieString()
287 {
288 LIMITED_METHOD_CONTRACT;
289 return m_strCookie;
290 }
291
292 inline ULONG GetCookieStringByteCount()
293 {
294 LIMITED_METHOD_CONTRACT;
295 return m_cCookieStrBytes;
296 }
297
298protected:
299 // Helper function to retrieve the custom marshaler object.
300 virtual CustomMarshalerInfo* GetCustomMarshalerInfo();
301
302private:
303 Assembly* m_pAssembly;
304 TypeHandle m_hndManagedType;
305 DWORD m_cMarshalerTypeNameBytes;
306 LPCUTF8 m_strMarshalerTypeName;
307 DWORD m_cCookieStrBytes;
308 LPCUTF8 m_strCookie;
309};
310
311
312#endif // _CUSTOMMARSHALERINFO_H_
313