Merge pull request #1109 from adbre/iss358
[mono.git] / mcs / class / corlib / System.Runtime.InteropServices / Marshal.cs
1 // System.Runtime.InteropServices.Marshal.cs
2 //
3 // Sean MacIsaac (macisaac@ximian.com)
4 // Paolo Molaro (lupus@ximian.com)
5 // Dietmar Maurer (dietmar@ximian.com)
6 // Jonathan Chambers (joncham@gmail.com)
7 //
8 // (C) 2001-2002 Ximian, Inc.
9
10 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System.Collections;
34 using System.Collections.Generic;
35 using System.Runtime.CompilerServices;
36 using System;
37 using System.Security;
38 using System.Reflection;
39 using System.Threading;
40
41 using System.Runtime.ConstrainedExecution;
42 #if !FULL_AOT_RUNTIME
43 using System.Runtime.InteropServices.ComTypes;
44 using Mono.Interop;
45 #endif
46
47 namespace System.Runtime.InteropServices
48 {
49         public static class Marshal
50         {
51                 /* fields */
52                 public static readonly int SystemMaxDBCSCharSize = 2; // don't know what this is
53                 public static readonly int SystemDefaultCharSize = Environment.IsRunningOnWindows ? 2 : 1;
54
55 #if !MOBILE
56                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
57                 private extern static int AddRefInternal (IntPtr pUnk);
58 #endif
59
60                 public static int AddRef (IntPtr pUnk)
61                 {
62 #if !MOBILE
63                         if (pUnk == IntPtr.Zero)
64                                 throw new ArgumentException ("Value cannot be null.", "pUnk");
65                         return AddRefInternal (pUnk);
66 #else
67                         throw new NotImplementedException ();
68 #endif
69                 }
70
71                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
72                 public extern static IntPtr AllocCoTaskMem (int cb);
73
74                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
75                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
76                 public extern static IntPtr AllocHGlobal (IntPtr cb);
77
78                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
79                 public static IntPtr AllocHGlobal (int cb)
80                 {
81                         return AllocHGlobal ((IntPtr)cb);
82                 }
83
84                 [MonoTODO]
85                 public static object BindToMoniker (string monikerName)
86                 {
87                         throw new NotImplementedException ();
88                 }
89
90                 [MonoTODO]
91                 public static void ChangeWrapperHandleStrength (object otp, bool fIsWeak)
92                 {
93                         throw new NotImplementedException ();
94                 }
95
96                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
97                 internal extern static void copy_to_unmanaged (Array source, int startIndex,
98                                                                IntPtr destination, int length);
99
100                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
101                 internal extern static void copy_from_unmanaged (IntPtr source, int startIndex,
102                                                                  Array destination, int length);
103
104                 public static void Copy (byte[] source, int startIndex, IntPtr destination, int length)
105                 {
106                         copy_to_unmanaged (source, startIndex, destination, length);
107                 }
108
109                 public static void Copy (char[] source, int startIndex, IntPtr destination, int length)
110                 {
111                         copy_to_unmanaged (source, startIndex, destination, length);
112                 }
113
114                 public static void Copy (short[] source, int startIndex, IntPtr destination, int length)
115                 {
116                         copy_to_unmanaged (source, startIndex, destination, length);
117                 }
118
119                 public static void Copy (int[] source, int startIndex, IntPtr destination, int length)
120                 {
121                         copy_to_unmanaged (source, startIndex, destination, length);
122                 }
123
124                 public static void Copy (long[] source, int startIndex, IntPtr destination, int length)
125                 {
126                         copy_to_unmanaged (source, startIndex, destination, length);
127                 }
128
129                 public static void Copy (float[] source, int startIndex, IntPtr destination, int length)
130                 {
131                         copy_to_unmanaged (source, startIndex, destination, length);
132                 }
133
134                 public static void Copy (double[] source, int startIndex, IntPtr destination, int length)
135                 {
136                         copy_to_unmanaged (source, startIndex, destination, length);
137                 }
138
139                 public static void Copy (IntPtr[] source, int startIndex, IntPtr destination, int length)
140                 {
141                         copy_to_unmanaged (source, startIndex, destination, length);
142                 }
143
144                 public static void Copy (IntPtr source, byte[] destination, int startIndex, int length)
145                 {
146                         copy_from_unmanaged (source, startIndex, destination, length);
147                 }
148
149                 public static void Copy (IntPtr source, char[] destination, int startIndex, int length)
150                 {
151                         copy_from_unmanaged (source, startIndex, destination, length);
152                 }
153
154                 public static void Copy (IntPtr source, short[] destination, int startIndex, int length)
155                 {
156                         copy_from_unmanaged (source, startIndex, destination, length);
157                 }
158
159                 public static void Copy (IntPtr source, int[] destination, int startIndex, int length)
160                 {
161                         copy_from_unmanaged (source, startIndex, destination, length);
162                 }
163
164                 public static void Copy (IntPtr source, long[] destination, int startIndex, int length)
165                 {
166                         copy_from_unmanaged (source, startIndex, destination, length);
167                 }
168
169                 public static void Copy (IntPtr source, float[] destination, int startIndex, int length)
170                 {
171                         copy_from_unmanaged (source, startIndex, destination, length);
172                 }
173
174                 public static void Copy (IntPtr source, double[] destination, int startIndex, int length)
175                 {
176                         copy_from_unmanaged (source, startIndex, destination, length);
177                 }
178
179                 public static void Copy (IntPtr source, IntPtr[] destination, int startIndex, int length)
180                 {
181                         copy_from_unmanaged (source, startIndex, destination, length);
182                 }
183
184                 public static IntPtr CreateAggregatedObject (IntPtr pOuter,
185                                                              object o)
186                 {
187                         throw new NotImplementedException ();
188                 }
189
190 #if NET_4_5
191                 public static IntPtr CreateAggregatedObject<T> (IntPtr pOuter, T o) {
192                         return CreateAggregatedObject (pOuter, (object)o);
193                 }
194 #endif
195
196 #if !FULL_AOT_RUNTIME
197                 public static object CreateWrapperOfType (object o, Type t)
198                 {
199                         __ComObject co = o as __ComObject;
200                         if (co == null)
201                                 throw new ArgumentException ("o must derive from __ComObject", "o");
202                         if (t == null)
203                                 throw new ArgumentNullException ("t");
204
205                         Type[] itfs = o.GetType ().GetInterfaces ();
206                         foreach (Type itf in itfs) {
207                                 if (itf.IsImport && co.GetInterface (itf) == IntPtr.Zero)
208                                         throw new InvalidCastException ();
209                         }
210
211                         return ComInteropProxy.GetProxy (co.IUnknown, t).GetTransparentProxy ();
212                 }
213
214 #if NET_4_5
215                 public static TWrapper CreateWrapperOfType<T, TWrapper> (T o) {
216                         return (TWrapper)CreateWrapperOfType ((object)o, typeof (TWrapper));
217                 }
218 #endif
219 #endif
220
221                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
222                 [ComVisible (true)]
223                 public extern static void DestroyStructure (IntPtr ptr, Type structuretype);
224
225 #if NET_4_5
226                 public static void DestroyStructure<T> (IntPtr ptr) {
227                         DestroyStructure (ptr, typeof (T));
228                 }
229 #endif                  
230
231                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
232                 public extern static void FreeBSTR (IntPtr ptr);
233
234                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
235                 public extern static void FreeCoTaskMem (IntPtr ptr);
236
237                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
238                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
239                 public extern static void FreeHGlobal (IntPtr hglobal);
240
241                 static void ClearBSTR (IntPtr ptr)
242                 {
243                         int len = ReadInt32 (ptr, -4);
244
245                         for (int i = 0; i < len; i++)
246                                 WriteByte (ptr, i, 0);
247                 }
248                 
249                 public static void ZeroFreeBSTR (IntPtr s)
250                 {
251                         ClearBSTR (s);
252                         FreeBSTR (s);
253                 }
254
255                 static void ClearAnsi (IntPtr ptr)
256                 {
257                         for (int i = 0; ReadByte (ptr, i) != 0; i++)
258                                 WriteByte (ptr, i, 0);
259                 }
260
261                 static void ClearUnicode (IntPtr ptr)
262                 {
263                         for (int i = 0; ReadInt16 (ptr, i) != 0; i += 2)
264                                 WriteInt16 (ptr, i, 0);
265                 }
266                 
267                 public static void ZeroFreeCoTaskMemAnsi (IntPtr s)
268                 {
269                         ClearAnsi (s);
270                         FreeCoTaskMem (s);
271                 }
272
273                 public static void ZeroFreeCoTaskMemUnicode (IntPtr s)
274                 {
275                         ClearUnicode (s);
276                         FreeCoTaskMem (s);
277                 }
278
279                 public static void ZeroFreeGlobalAllocAnsi (IntPtr s)
280                 {
281                         ClearAnsi (s);
282                         FreeHGlobal (s);
283                 }
284
285                 public static void ZeroFreeGlobalAllocUnicode (IntPtr s)
286                 {
287                         ClearUnicode (s);
288                         FreeHGlobal (s);
289                 }
290
291 #if !FULL_AOT_RUNTIME
292                 public static Guid GenerateGuidForType (Type type)
293                 {
294                         return type.GUID;
295                 }
296
297                 public static string GenerateProgIdForType (Type type)
298                 {
299                         IList<CustomAttributeData> attrs = CustomAttributeData.GetCustomAttributes (type);
300
301                         foreach (var a in attrs)
302                         {
303                                 var dt = a.Constructor.DeclaringType;
304                                 string name = dt.Name;
305                                 if (name == "ProgIdAttribute")
306                                 {
307                                         var args = a.ConstructorArguments;
308                                         string text = a.ConstructorArguments[0].Value as string;
309                                         if (text == null)
310                                         {
311                                                 text = string.Empty;
312                                         }
313                                         return text;
314                                 }
315                         }
316
317                         return type.FullName;
318                 }
319
320                 [MonoTODO]
321                 public static object GetActiveObject (string progID)
322                 {
323                         throw new NotImplementedException ();
324                 }
325
326 #if !MOBILE
327                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
328                 private extern static IntPtr GetCCW (object o, Type T);
329
330                 private static IntPtr GetComInterfaceForObjectInternal (object o, Type T)
331                 {
332                         if (IsComObject (o))
333                                 return ((__ComObject)o).GetInterface (T);
334                         else
335                                 return GetCCW (o, T);
336                 }
337 #endif
338
339                 public static IntPtr GetComInterfaceForObject (object o, Type T)
340                 {
341 #if !MOBILE
342                         IntPtr pItf = GetComInterfaceForObjectInternal (o, T);
343                         AddRef (pItf);
344                         return pItf;
345 #else
346                         throw new NotImplementedException ();
347 #endif
348                 }
349
350 #if NET_4_5
351                 public static IntPtr GetComInterfaceForObject<T, TInterface> (T o) {
352                         return GetComInterfaceForObject ((object)o, typeof (T));
353                 }
354 #endif                  
355
356                 [MonoTODO]
357                 public static IntPtr GetComInterfaceForObjectInContext (object o, Type t)
358                 {
359                         throw new NotImplementedException ();
360                 }
361
362                 [MonoNotSupportedAttribute ("MSDN states user code should never need to call this method.")]
363                 public static object GetComObjectData (object obj, object key)
364                 {
365                         throw new NotSupportedException ("MSDN states user code should never need to call this method.");
366                 }
367
368 #if !MOBILE
369                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
370                 private extern static int GetComSlotForMethodInfoInternal (MemberInfo m);
371 #endif
372
373                 public static int GetComSlotForMethodInfo (MemberInfo m)
374                 {
375 #if !MOBILE
376                         if (m == null)
377                                 throw new ArgumentNullException ("m");
378                         if (!(m is MethodInfo))
379                                 throw new ArgumentException ("The MemberInfo must be an interface method.", "m");
380                         if (!m.DeclaringType.IsInterface)
381                                 throw new ArgumentException ("The MemberInfo must be an interface method.", "m");
382                         return GetComSlotForMethodInfoInternal (m);
383 #else
384                         throw new NotImplementedException ();
385 #endif
386                 }
387
388                 [MonoTODO]
389                 public static int GetEndComSlot (Type t)
390                 {
391                         throw new NotImplementedException ();
392                 }
393
394                 [MonoTODO]
395                 public static int GetExceptionCode()
396                 {
397                         throw new NotImplementedException ();
398                 }
399
400                 [MonoTODO]
401                 [ComVisible (true)]
402                 public static IntPtr GetExceptionPointers()
403                 {
404                         throw new NotImplementedException ();
405                 }
406
407                 public static IntPtr GetHINSTANCE (Module m)
408                 {
409                         if (m == null)
410                                 throw new ArgumentNullException ("m");
411
412                         return m.GetHINSTANCE ();
413                 }
414 #endif // !FULL_AOT_RUNTIME
415
416 #if !FULL_AOT_RUNTIME
417                 [MonoTODO ("SetErrorInfo")]
418                 public static int GetHRForException (Exception e)
419                 {
420                         return e.hresult;
421                 }
422
423                 [MonoTODO]
424                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
425                 public static int GetHRForLastWin32Error()
426                 {
427                         throw new NotImplementedException ();
428                 }
429
430                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
431                 private extern static IntPtr GetIDispatchForObjectInternal (object o);
432
433                 public static IntPtr GetIDispatchForObject (object o)
434                 {
435                         IntPtr pUnk = GetIDispatchForObjectInternal (o);
436                         // Internal method does not AddRef
437                         AddRef (pUnk);
438                         return pUnk;
439                 }
440
441                 [MonoTODO]
442                 public static IntPtr GetIDispatchForObjectInContext (object o)
443                 {
444                         throw new NotImplementedException ();
445                 }
446
447                 [MonoTODO]
448                 public static IntPtr GetITypeInfoForType (Type t)
449                 {
450                         throw new NotImplementedException ();
451                 }
452
453                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
454                 private extern static IntPtr GetIUnknownForObjectInternal (object o);
455
456                 public static IntPtr GetIUnknownForObject (object o)
457                 {
458                         IntPtr pUnk = GetIUnknownForObjectInternal (o);
459                         // Internal method does not AddRef
460                         AddRef (pUnk);
461                         return pUnk;
462                 }
463
464                 [MonoTODO]
465                 public static IntPtr GetIUnknownForObjectInContext (object o)
466                 {
467                         throw new NotImplementedException ();
468                 }
469
470                 [MonoTODO]
471                 [Obsolete ("This method has been deprecated")]
472                 public static IntPtr GetManagedThunkForUnmanagedMethodPtr (IntPtr pfnMethodToWrap, IntPtr pbSignature, int cbSignature)
473                 {
474                         throw new NotImplementedException ();
475                 }
476
477                 [MonoTODO]
478                 public static MemberInfo GetMethodInfoForComSlot (Type t, int slot, ref ComMemberType memberType)
479                 {
480                         throw new NotImplementedException ();
481                 }
482
483                 public static void GetNativeVariantForObject (object obj, IntPtr pDstNativeVariant)
484                 {
485                         Variant vt = new Variant();
486                         vt.SetValue(obj);
487                         Marshal.StructureToPtr(vt, pDstNativeVariant, false);
488                 }
489
490 #if NET_4_5
491                 public static void GetNativeVariantForObject<T> (T obj, IntPtr pDstNativeVariant) {
492                         GetNativeVariantForObject ((object)obj, pDstNativeVariant);
493                 }
494 #endif
495
496 #if !MOBILE
497                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
498                 private static extern object GetObjectForCCW (IntPtr pUnk);
499 #endif
500
501                 public static object GetObjectForIUnknown (IntPtr pUnk)
502                 {
503 #if !MOBILE
504                         object obj = GetObjectForCCW (pUnk);
505                         // was not a CCW
506                         if (obj == null) {
507                                 ComInteropProxy proxy = ComInteropProxy.GetProxy (pUnk, typeof (__ComObject));
508                                 obj = proxy.GetTransparentProxy ();
509                         }
510                         return obj;
511 #else
512                         throw new NotImplementedException ();
513 #endif
514                 }
515
516                 public static object GetObjectForNativeVariant (IntPtr pSrcNativeVariant)
517                 {
518                         Variant vt = (Variant)Marshal.PtrToStructure(pSrcNativeVariant, typeof(Variant));
519                         return vt.GetValue();
520                 }
521
522 #if NET_4_5
523                 public static T GetObjectForNativeVariant<T> (IntPtr pSrcNativeVariant) {
524                         Variant vt = (Variant)Marshal.PtrToStructure(pSrcNativeVariant, typeof(Variant));
525                         return (T)vt.GetValue();
526                 }
527 #endif
528
529                 public static object[] GetObjectsForNativeVariants (IntPtr aSrcNativeVariant, int cVars)
530                 {
531                         if (cVars < 0)
532                                 throw new ArgumentOutOfRangeException ("cVars", "cVars cannot be a negative number.");
533                         object[] objects = new object[cVars];
534                         for (int i = 0; i < cVars; i++)
535                                 objects[i] = GetObjectForNativeVariant ((IntPtr)(aSrcNativeVariant.ToInt64 () +
536                                         i * SizeOf (typeof(Variant))));
537                         return objects;
538                 }
539
540 #if NET_4_5
541                 public static T[] GetObjectsForNativeVariants<T> (IntPtr aSrcNativeVariant, int cVars) {
542                         if (cVars < 0)
543                                 throw new ArgumentOutOfRangeException ("cVars", "cVars cannot be a negative number.");
544                         T[] objects = new T[cVars];
545                         for (int i = 0; i < cVars; i++)
546                                 objects[i] = GetObjectForNativeVariant<T> ((IntPtr)(aSrcNativeVariant.ToInt64 () +
547                                         i * SizeOf (typeof(Variant))));
548                         return objects;
549                 }
550 #endif
551
552                 [MonoTODO]
553                 public static int GetStartComSlot (Type t)
554                 {
555                         throw new NotImplementedException ();
556                 }
557
558                 [MonoTODO]
559                 [Obsolete ("This method has been deprecated")]
560                 public static Thread GetThreadFromFiberCookie (int cookie)
561                 {
562                         throw new NotImplementedException ();
563                 }
564
565                 public static object GetTypedObjectForIUnknown (IntPtr pUnk, Type t)
566                 {
567                         ComInteropProxy proxy = new ComInteropProxy (pUnk, t);
568                         __ComObject co = (__ComObject)proxy.GetTransparentProxy ();
569                         foreach (Type itf in t.GetInterfaces ()) {
570                                 if ((itf.Attributes & TypeAttributes.Import) == TypeAttributes.Import) {
571                                         if (co.GetInterface (itf) == IntPtr.Zero)
572                                                 return null;
573                                 }
574                         }
575                         return co;
576                 }
577
578                 [MonoTODO]
579                 public static Type GetTypeForITypeInfo (IntPtr piTypeInfo)
580                 {
581                         throw new NotImplementedException ();
582                 }
583
584 #if NET_4_5
585                 public static Type GetTypeFromCLSID (Guid clsid)
586                 {
587                         throw new NotImplementedException ();                   
588                 }
589 #endif
590
591 #if !FULL_AOT_RUNTIME
592                 [Obsolete]
593                 [MonoTODO]
594                 public static string GetTypeInfoName (UCOMITypeInfo pTI)
595                 {
596                         throw new NotImplementedException ();
597                 }
598
599                 public static string GetTypeInfoName (ITypeInfo typeInfo)
600                 {
601                         throw new NotImplementedException ();
602                 }
603
604                 [Obsolete]
605                 [MonoTODO]
606                 public static Guid GetTypeLibGuid (UCOMITypeLib pTLB)
607                 {
608                         throw new NotImplementedException ();
609                 }
610
611                 [MonoTODO]
612                 public static Guid GetTypeLibGuid (ITypeLib typelib)
613                 {
614                         throw new NotImplementedException ();
615                 }
616
617                 [MonoTODO]
618                 public static Guid GetTypeLibGuidForAssembly (Assembly asm)
619                 {
620                         throw new NotImplementedException ();
621                 }
622
623                 [Obsolete]
624                 [MonoTODO]
625                 public static int GetTypeLibLcid (UCOMITypeLib pTLB)
626                 {
627                         throw new NotImplementedException ();
628                 }
629
630                 [MonoTODO]
631                 public static int GetTypeLibLcid (ITypeLib typelib)
632                 {
633                         throw new NotImplementedException ();
634                 }
635
636                 [Obsolete]
637                 [MonoTODO]
638                 public static string GetTypeLibName (UCOMITypeLib pTLB)
639                 {
640                         throw new NotImplementedException ();
641                 }
642
643                 [MonoTODO]
644                 public static string GetTypeLibName (ITypeLib typelib)
645                 {
646                         throw new NotImplementedException ();
647                 }
648
649                 [MonoTODO]
650                 public static void GetTypeLibVersionForAssembly (Assembly inputAssembly, out int majorVersion, out int minorVersion)
651                 {
652                         throw new NotImplementedException ();
653                 }
654
655                 public static object GetUniqueObjectForIUnknown (IntPtr unknown)
656                 {
657                         throw new NotImplementedException ();
658                 }
659 #endif
660
661                 [MonoTODO]
662                 [Obsolete ("This method has been deprecated")]
663                 public static IntPtr GetUnmanagedThunkForManagedMethodPtr (IntPtr pfnMethodToWrap, IntPtr pbSignature, int cbSignature)
664                 {
665                         throw new NotImplementedException ();
666                 }
667
668 #if !MOBILE
669                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
670                 public extern static bool IsComObject (object o);
671 #else
672                 public static bool IsComObject (object o)
673                 {
674                         throw new NotImplementedException ();
675                 }
676 #endif          
677
678                 [MonoTODO]
679                 public static bool IsTypeVisibleFromCom (Type t)
680                 {
681                         throw new NotImplementedException ();
682                 }
683
684                 [MonoTODO]
685                 public static int NumParamBytes (MethodInfo m)
686                 {
687                         throw new NotImplementedException ();
688                 }
689 #endif
690
691                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
692                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
693                 public static extern int GetLastWin32Error();
694
695                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
696                 public extern static IntPtr OffsetOf (Type t, string fieldName);
697
698 #if NET_4_5
699                 public static IntPtr OffsetOf<T> (string fieldName) {
700                         return OffsetOf (typeof (T), fieldName);
701                 }
702 #endif
703
704                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
705                 public extern static void Prelink (MethodInfo m);
706
707                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
708                 public extern static void PrelinkAll (Type c);
709
710                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
711                 public extern static string PtrToStringAnsi (IntPtr ptr);
712                 
713                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
714                 public extern static string PtrToStringAnsi (IntPtr ptr, int len);
715
716                 public static string PtrToStringAuto (IntPtr ptr)
717                 {
718                         return SystemDefaultCharSize == 2
719                                 ? PtrToStringUni (ptr) : PtrToStringAnsi (ptr);
720                 }
721                 
722                 public static string PtrToStringAuto (IntPtr ptr, int len)
723                 {
724                         return SystemDefaultCharSize == 2
725                                 ? PtrToStringUni (ptr, len) : PtrToStringAnsi (ptr, len);
726                 }
727
728                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
729                 public extern static string PtrToStringUni (IntPtr ptr);
730
731                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
732                 public extern static string PtrToStringUni (IntPtr ptr, int len);
733
734 #if !MOBILE
735                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
736                 public extern static string PtrToStringBSTR (IntPtr ptr);
737 #else
738                 public static string PtrToStringBSTR (IntPtr ptr)
739                 {
740                         throw new NotImplementedException ();
741                 }
742 #endif
743                 
744                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
745                 [ComVisible (true)]
746                 public extern static void PtrToStructure (IntPtr ptr, object structure);
747
748                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
749                 [ComVisible (true)]
750                 public extern static object PtrToStructure (IntPtr ptr, Type structureType);
751
752 #if NET_4_5
753                 public static void PtrToStructure<T> (IntPtr ptr, T structure) {
754                         PtrToStructure (ptr, (object)structure);
755                 }
756
757                 public static T PtrToStructure<T> (IntPtr ptr) {
758                         return (T) PtrToStructure (ptr, typeof (T));
759                 }
760 #endif
761
762 #if !MOBILE
763                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
764                 private extern static int QueryInterfaceInternal (IntPtr pUnk, ref Guid iid, out IntPtr ppv);
765 #endif
766
767                 public static int QueryInterface (IntPtr pUnk, ref Guid iid, out IntPtr ppv)
768                 {
769 #if !MOBILE
770                         if (pUnk == IntPtr.Zero)
771                                 throw new ArgumentException ("Value cannot be null.", "pUnk");
772                         return QueryInterfaceInternal (pUnk, ref iid, out ppv);
773 #else
774                         throw new NotImplementedException ();
775 #endif
776                 }
777
778                 public static byte ReadByte (IntPtr ptr)
779                 {
780                         unsafe {
781                                 return *(byte*)ptr;
782                         }
783                 }
784
785                 public static byte ReadByte (IntPtr ptr, int ofs) {
786                         unsafe {
787                                 return *((byte*)ptr + ofs);
788                         }
789                 }
790
791                 [MonoTODO]
792                 [SuppressUnmanagedCodeSecurity]
793                 public static byte ReadByte ([In, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs)
794                 {
795                         throw new NotImplementedException ();
796                 }
797
798                 public unsafe static short ReadInt16 (IntPtr ptr)
799                 {
800                         byte *addr = (byte *) ptr;
801                         
802                         // The mono JIT can't inline this due to the hight number of calls
803                         // return ReadInt16 (ptr, 0);
804                         
805                         if (((uint)addr & 1) == 0) 
806                                 return *(short*)addr;
807
808                         short s;
809                         String.memcpy ((byte*)&s, (byte*)ptr, 2);
810                         return s;
811                 }
812
813                 public unsafe static short ReadInt16 (IntPtr ptr, int ofs)
814                 {
815                         byte *addr = ((byte *) ptr) + ofs;
816
817                         if (((uint) addr & 1) == 0)
818                                 return *(short*)addr;
819
820                         short s;
821                         String.memcpy ((byte*)&s, addr, 2);
822                         return s;
823                 }
824
825                 [MonoTODO]
826                 [SuppressUnmanagedCodeSecurity]
827                 public static short ReadInt16 ([In, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs)
828                 {
829                         throw new NotImplementedException ();
830                 }
831
832                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
833                 public unsafe static int ReadInt32 (IntPtr ptr)
834                 {
835                         byte *addr = (byte *) ptr;
836                         
837                         if (((uint)addr & 3) == 0) 
838                                 return *(int*)addr;
839
840                         int s;
841                         String.memcpy ((byte*)&s, addr, 4);
842                         return s;
843                 }
844
845                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
846                 public unsafe static int ReadInt32 (IntPtr ptr, int ofs)
847                 {
848                         byte *addr = ((byte *) ptr) + ofs;
849                         
850                         if ((((int) addr) & 3) == 0)
851                                 return *(int*)addr;
852                         else {
853                                 int s;
854                                 String.memcpy ((byte*)&s, addr, 4);
855                                 return s;
856                         }
857                 }
858
859                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
860                 [MonoTODO]
861                 [SuppressUnmanagedCodeSecurity]
862                 public static int ReadInt32 ([In, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs)
863                 {
864                         throw new NotImplementedException ();
865                 }
866
867                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
868                 public unsafe static long ReadInt64 (IntPtr ptr)
869                 {
870                         byte *addr = (byte *) ptr;
871                                 
872                         // The real alignment might be 4 on some platforms, but this is just an optimization,
873                         // so it doesn't matter.
874                         if (((uint) addr & 7) == 0)
875                                 return *(long*)ptr;
876
877                         long s;
878                         String.memcpy ((byte*)&s, addr, 8);
879                         return s;
880                 }
881
882                 public unsafe static long ReadInt64 (IntPtr ptr, int ofs)
883                 {
884                         byte *addr = ((byte *) ptr) + ofs;
885
886                         if (((uint) addr & 7) == 0)
887                                 return *(long*)addr;
888                         
889                         long s;
890                         String.memcpy ((byte*)&s, addr, 8);
891                         return s;
892                 }
893
894                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
895                 [MonoTODO]
896                 [SuppressUnmanagedCodeSecurity]
897                 public static long ReadInt64 ([In, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs)
898                 {
899                         throw new NotImplementedException ();
900                 }
901
902                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
903                 public static IntPtr ReadIntPtr (IntPtr ptr)
904                 {
905                         if (IntPtr.Size == 4)
906                                 return (IntPtr)ReadInt32 (ptr);
907                         else
908                                 return (IntPtr)ReadInt64 (ptr);
909                 }
910                 
911                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
912                 public static IntPtr ReadIntPtr (IntPtr ptr, int ofs)
913                 {
914                         if (IntPtr.Size == 4)
915                                 return (IntPtr)ReadInt32 (ptr, ofs);
916                         else
917                                 return (IntPtr)ReadInt64 (ptr, ofs);
918                 }
919
920                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
921                 [MonoTODO]
922                 public static IntPtr ReadIntPtr ([In, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs)
923                 {
924                         throw new NotImplementedException ();
925                 }
926
927                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
928                 public extern static IntPtr ReAllocCoTaskMem (IntPtr pv, int cb);
929
930                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
931                 public extern static IntPtr ReAllocHGlobal (IntPtr pv, IntPtr cb);
932
933 #if !MOBILE
934                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
935                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
936                 private extern static int ReleaseInternal (IntPtr pUnk);
937 #endif
938
939                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
940                 public static int Release (IntPtr pUnk)
941                 {
942 #if !MOBILE
943                         if (pUnk == IntPtr.Zero)
944                                 throw new ArgumentException ("Value cannot be null.", "pUnk");
945
946                         return ReleaseInternal (pUnk);
947 #else
948                         throw new NotImplementedException ();
949 #endif
950                 }
951
952 #if !FULL_AOT_RUNTIME
953                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
954                 private extern static int ReleaseComObjectInternal (object co);
955
956                 public static int ReleaseComObject (object o)
957                 {
958                         if (o == null)
959                                 throw new ArgumentException ("Value cannot be null.", "o");
960                         if (!IsComObject (o))
961                                 throw new ArgumentException ("Value must be a Com object.", "o");
962                         return ReleaseComObjectInternal (o);
963                 }
964
965                 [Obsolete]
966                 [MonoTODO]
967                 public static void ReleaseThreadCache()
968                 {
969                         throw new NotImplementedException ();
970                 }
971
972                 [MonoNotSupportedAttribute ("MSDN states user code should never need to call this method.")]
973                 public static bool SetComObjectData (object obj, object key, object data)
974                 {
975                         throw new NotSupportedException ("MSDN states user code should never need to call this method.");
976                 }
977 #endif
978
979                 [ComVisible (true)]
980                 public static int SizeOf (object structure)
981                 {
982                         return SizeOf (structure.GetType ());
983                 }
984
985                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
986                 public extern static int SizeOf (Type t);
987
988 #if NET_4_5
989                 public static int SizeOf<T> () {
990                         return SizeOf (typeof (T));
991                 }
992
993                 public static int SizeOf<T> (T structure) {
994                         return SizeOf (structure.GetType ());
995                 }
996 #endif
997
998                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
999                 public extern static IntPtr StringToBSTR (string s);
1000
1001                 //
1002                 // I believe this is wrong, because in Mono and in P/Invoke
1003                 // we treat "Ansi" conversions as UTF-8 conversions, while
1004                 // this one does not do this
1005                 //
1006                 public static IntPtr StringToCoTaskMemAnsi (string s)
1007                 {
1008                         int length = s.Length + 1;
1009                         IntPtr ctm = AllocCoTaskMem (length);
1010
1011                         byte[] asBytes = new byte[length];
1012                         for (int i = 0; i < s.Length; i++)
1013                                 asBytes[i] = (byte)s[i];
1014                         asBytes[s.Length] = 0;
1015
1016                         copy_to_unmanaged (asBytes, 0, ctm, length);
1017                         return ctm;
1018                 }
1019
1020                 public static IntPtr StringToCoTaskMemAuto (string s)
1021                 {
1022                         return SystemDefaultCharSize == 2
1023                                 ? StringToCoTaskMemUni (s) : StringToCoTaskMemAnsi (s);
1024                 }
1025
1026                 public static IntPtr StringToCoTaskMemUni (string s)
1027                 {
1028                         int length = s.Length + 1;
1029                         IntPtr ctm = AllocCoTaskMem (length * 2);
1030                         
1031                         char[] asChars = new char[length];
1032                         s.CopyTo (0, asChars, 0, s.Length);
1033                         asChars[s.Length] = '\0';
1034
1035                         copy_to_unmanaged (asChars, 0, ctm, length);
1036                         return ctm;
1037                 }
1038
1039                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1040                 public extern static IntPtr StringToHGlobalAnsi (string s);
1041
1042                 public static IntPtr StringToHGlobalAuto (string s)
1043                 {
1044                         return SystemDefaultCharSize == 2
1045                                 ? StringToHGlobalUni (s) : StringToHGlobalAnsi (s);
1046                 }
1047
1048                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1049                 public extern static IntPtr StringToHGlobalUni (string s);
1050
1051                 public static IntPtr SecureStringToBSTR (SecureString s)
1052                 {
1053                         if (s == null)
1054                                 throw new ArgumentNullException ("s");
1055                         int len = s.Length;
1056                         IntPtr ctm = AllocCoTaskMem ((len+1) * 2 + 4);
1057                         byte [] buffer = null;
1058                         WriteInt32 (ctm, 0, len*2);
1059                         try {
1060                                 buffer = s.GetBuffer ();
1061
1062                                 for (int i = 0; i < len; i++)
1063                                         WriteInt16 (ctm, 4 + (i * 2), (short) ((buffer [(i*2)] << 8) | (buffer [i*2+1])));
1064                                 WriteInt16 (ctm, 4 + buffer.Length, 0);
1065                         } finally {
1066                                 if (buffer != null)
1067                                         for (int i = buffer.Length; i > 0; ){
1068                                                 i--;
1069                                                 buffer [i] = 0;
1070                                         }
1071                         }
1072                         return (IntPtr) ((long)ctm + 4);
1073                 }
1074
1075                 public static IntPtr SecureStringToCoTaskMemAnsi (SecureString s)
1076                 {
1077                         if (s == null)
1078                                 throw new ArgumentNullException ("s");
1079                         int len = s.Length;
1080                         IntPtr ctm = AllocCoTaskMem (len + 1);
1081                         byte [] copy = new byte [len+1];
1082
1083                         try {
1084                                 byte [] buffer = s.GetBuffer ();
1085                                 int i = 0, j = 0;
1086                                 for (; i < len; i++, j += 2){
1087                                         copy [i] = buffer [j+1];
1088                                         buffer [j] = 0;
1089                                         buffer [j+1] = 0;
1090                                 }
1091                                 copy [i] = 0;
1092                                 copy_to_unmanaged (copy, 0, ctm, len+1);
1093                         } finally {
1094                                 // Ensure that we clear the buffer.
1095                                 for (int i = len; i > 0; ){
1096                                         i--;
1097                                         copy [i] = 0;
1098                                 }
1099                         }
1100                         return ctm;
1101                 }
1102
1103                 public static IntPtr SecureStringToCoTaskMemUnicode (SecureString s)
1104                 {
1105                         if (s == null)
1106                                 throw new ArgumentNullException ("s");
1107                         int len = s.Length;
1108                         IntPtr ctm = AllocCoTaskMem (len * 2 + 2);
1109                         byte [] buffer = null;
1110                         try {
1111                                 buffer = s.GetBuffer ();
1112                                 for (int i = 0; i < len; i++)
1113                                         WriteInt16 (ctm, i * 2, (short) ((buffer [(i*2)] << 8) | (buffer [i*2+1])));
1114                                 WriteInt16 (ctm, buffer.Length, 0);
1115                         } finally {
1116                                 if (buffer != null)
1117                                         for (int i = buffer.Length; i > 0; ){
1118                                                 i--;
1119                                                 buffer [i] = 0;
1120                                         }
1121                         }
1122                         return ctm;
1123                 }
1124
1125                 public static IntPtr SecureStringToGlobalAllocAnsi (SecureString s)
1126                 {
1127                         if (s == null)
1128                                 throw new ArgumentNullException ("s");
1129                         return SecureStringToCoTaskMemAnsi (s);
1130                 }
1131
1132                 public static IntPtr SecureStringToGlobalAllocUnicode (SecureString s)
1133                 {
1134                         if (s == null)
1135                                 throw new ArgumentNullException ("s");
1136                         return SecureStringToCoTaskMemUnicode (s);
1137                 }
1138
1139                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
1140                 [ComVisible (true)]
1141                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1142                 public extern static void StructureToPtr (object structure, IntPtr ptr, bool fDeleteOld);
1143
1144 #if NET_4_5
1145                 public static void StructureToPtr<T> (T structure, IntPtr ptr, bool fDeleteOld) {
1146                         StructureToPtr ((object)structure, ptr, fDeleteOld);
1147                 }
1148 #endif
1149
1150                 public static void ThrowExceptionForHR (int errorCode) {
1151                         Exception ex = GetExceptionForHR (errorCode);
1152                         if (ex != null)
1153                                 throw ex;
1154                 }
1155
1156                 public static void ThrowExceptionForHR (int errorCode, IntPtr errorInfo) {
1157                         Exception ex = GetExceptionForHR (errorCode, errorInfo);
1158                         if (ex != null)
1159                                 throw ex;
1160                 }
1161
1162                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1163                 public extern static IntPtr UnsafeAddrOfPinnedArrayElement (Array arr, int index);
1164
1165 #if NET_4_5
1166                 public static IntPtr UnsafeAddrOfPinnedArrayElement<T> (T[] arr, int index) {
1167                         return UnsafeAddrOfPinnedArrayElement ((Array)arr, index);
1168                 }
1169 #endif
1170
1171                 public static void WriteByte (IntPtr ptr, byte val)
1172                 {
1173                         unsafe {
1174                                 *(byte*)ptr = val;
1175                         }
1176                 }
1177
1178                 public static void WriteByte (IntPtr ptr, int ofs, byte val) {
1179                         unsafe {
1180                                 *(byte*)(IntPtr.Add (ptr, ofs)) = val;
1181                         }
1182                 }
1183
1184                 [MonoTODO]
1185                 [SuppressUnmanagedCodeSecurity]
1186                 public static void WriteByte ([In, Out, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs, byte val)
1187                 {
1188                         throw new NotImplementedException ();
1189                 }
1190
1191                 public static unsafe void WriteInt16 (IntPtr ptr, short val)
1192                 {
1193                         byte *addr = (byte *) ptr;
1194                         
1195                         if (((uint)addr & 1) == 0)
1196                                 *(short*)addr = val;
1197                         else
1198                                 String.memcpy (addr, (byte*)&val, 2);
1199                 }
1200
1201                 public static unsafe void WriteInt16 (IntPtr ptr, int ofs, short val)
1202                 {
1203                         byte *addr = ((byte *) ptr) + ofs;
1204
1205                         if (((uint)addr & 1) == 0)
1206                                 *(short*)addr = val;
1207                         else {
1208                                 String.memcpy (addr, (byte*)&val, 2);
1209                         }
1210                 }
1211
1212                 [MonoTODO]
1213                 [SuppressUnmanagedCodeSecurity]
1214                 public static void WriteInt16 ([In, Out, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs, short val)
1215                 {
1216                         throw new NotImplementedException ();
1217                 }
1218
1219                 public static void WriteInt16 (IntPtr ptr, char val)
1220                 {
1221                         WriteInt16 (ptr, 0, (short)val);
1222                 }
1223
1224                 public static void WriteInt16 (IntPtr ptr, int ofs, char val)
1225                 {
1226                         WriteInt16 (ptr, ofs, (short)val);
1227                 }
1228
1229                 [MonoTODO]
1230                 public static void WriteInt16([In, Out] object ptr, int ofs, char val)
1231                 {
1232                         throw new NotImplementedException ();
1233                 }
1234
1235                 public static unsafe void WriteInt32 (IntPtr ptr, int val)
1236                 {
1237                         byte *addr = (byte *) ptr;
1238                         
1239                         if (((uint)addr & 3) == 0) 
1240                                 *(int*)addr = val;
1241                         else {
1242                                 String.memcpy (addr, (byte*)&val, 4);
1243                         }
1244                 }
1245
1246                 public unsafe static void WriteInt32 (IntPtr ptr, int ofs, int val)
1247                 {
1248                         byte *addr = ((byte *) ptr) + ofs;
1249
1250                         if (((uint)addr & 3) == 0) 
1251                                 *(int*)addr = val;
1252                         else {
1253                                 String.memcpy (addr, (byte*)&val, 4);
1254                         }
1255                 }
1256
1257                 [MonoTODO]
1258                 [SuppressUnmanagedCodeSecurity]
1259                 public static void WriteInt32([In, Out, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs, int val)
1260                 {
1261                         throw new NotImplementedException ();
1262                 }
1263
1264                 public static unsafe void WriteInt64 (IntPtr ptr, long val)
1265                 {
1266                         byte *addr = (byte *) ptr;
1267                         
1268                         // The real alignment might be 4 on some platforms, but this is just an optimization,
1269                         // so it doesn't matter.
1270                         if (((uint)addr & 7) == 0) 
1271                                 *(long*)addr = val;
1272                         else 
1273                                 String.memcpy (addr, (byte*)&val, 8);
1274                 }
1275
1276                 public static unsafe void WriteInt64 (IntPtr ptr, int ofs, long val)
1277                 {
1278                         byte *addr = ((byte *) ptr) + ofs;
1279
1280                         // The real alignment might be 4 on some platforms, but this is just an optimization,
1281                         // so it doesn't matter.
1282                         if (((uint)addr & 7) == 0) 
1283                                 *(long*)addr = val;
1284                         else 
1285                                 String.memcpy (addr, (byte*)&val, 8);
1286                 }
1287
1288                 [MonoTODO]
1289                 [SuppressUnmanagedCodeSecurity]
1290                 public static void WriteInt64 ([In, Out, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs, long val)
1291                 {
1292                         throw new NotImplementedException ();
1293                 }
1294
1295                 public static void WriteIntPtr (IntPtr ptr, IntPtr val)
1296                 {
1297                         if (IntPtr.Size == 4)
1298                                 WriteInt32 (ptr, (int)val);
1299                         else
1300                                 WriteInt64 (ptr, (long)val);
1301                 }
1302
1303                 public static void WriteIntPtr (IntPtr ptr, int ofs, IntPtr val)
1304                 {
1305                         if (IntPtr.Size == 4)
1306                                 WriteInt32 (ptr, ofs, (int)val);
1307                         else
1308                                 WriteInt64 (ptr, ofs, (long)val);
1309                 }
1310
1311                 [MonoTODO]
1312                 public static void WriteIntPtr([In, Out, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs, IntPtr val)
1313                 {
1314                         throw new NotImplementedException ();
1315                 }
1316
1317                 public static Exception GetExceptionForHR (int errorCode) {
1318                         return GetExceptionForHR (errorCode, IntPtr.Zero);
1319                 }
1320
1321                 public static Exception GetExceptionForHR (int errorCode, IntPtr errorInfo) {
1322
1323                         const int E_OUTOFMEMORY = unchecked ((int)0x8007000EL);
1324                         const int E_INVALIDARG = unchecked ((int)0X80070057);
1325                         
1326                         switch (errorCode)
1327                         {
1328                         case E_OUTOFMEMORY:
1329                                 return new OutOfMemoryException ();
1330                         case E_INVALIDARG:
1331                                 return new ArgumentException ();
1332                         }
1333                         if (errorCode < 0)
1334                                 return new COMException ("", errorCode);
1335                         return null;
1336                 }
1337
1338 #if !FULL_AOT_RUNTIME
1339                 public static int FinalReleaseComObject (object o)
1340                 {
1341                         while (ReleaseComObject (o) != 0);
1342                         return 0;
1343                 }
1344 #endif
1345
1346                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1347                 private static extern Delegate GetDelegateForFunctionPointerInternal (IntPtr ptr, Type t);
1348
1349                 public static Delegate GetDelegateForFunctionPointer (IntPtr ptr, Type t)
1350                 {
1351                         if (t == null)
1352                                 throw new ArgumentNullException ("t");
1353                         if (!t.IsSubclassOf (typeof (MulticastDelegate)) || (t == typeof (MulticastDelegate)))
1354                                 throw new ArgumentException ("Type is not a delegate", "t");
1355                         if (t.IsGenericType)
1356                                 throw new ArgumentException ("The specified Type must not be a generic type definition.");
1357                         if (ptr == IntPtr.Zero)
1358                                 throw new ArgumentNullException ("ptr");
1359
1360                         return GetDelegateForFunctionPointerInternal (ptr, t);
1361                 }
1362
1363 #if NET_4_5
1364                 public static TDelegate GetDelegateForFunctionPointer<TDelegate> (IntPtr ptr) {
1365                         return (TDelegate) (object) GetDelegateForFunctionPointer (ptr, typeof (TDelegate));
1366                 }
1367 #endif
1368
1369                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1370                 private static extern IntPtr GetFunctionPointerForDelegateInternal (Delegate d);
1371                 
1372                 public static IntPtr GetFunctionPointerForDelegate (Delegate d)
1373                 {
1374                         if (d == null)
1375                                 throw new ArgumentNullException ("d");
1376                         
1377                         return GetFunctionPointerForDelegateInternal (d);
1378                 }
1379
1380 #if NET_4_5
1381                 public static IntPtr GetFunctionPointerForDelegate<TDelegate> (TDelegate d) {
1382                         if (d == null)
1383                                 throw new ArgumentNullException ("d");
1384                         
1385                         return GetFunctionPointerForDelegateInternal ((Delegate)(object)d);
1386                 }
1387 #endif
1388         }
1389 }