mirror of https://github.com/mono/CppSharp.git
c-sharpdotnetmonobindingsbridgecclangcpluspluscppsharpglueinteropparserparsingpinvokeswigsyntax-treevisitorsxamarinxamarin-bindings
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
3.1 KiB
74 lines
3.1 KiB
// |
|
// Mono.VisualC.Interop.Util.DelegateTypeCache.cs: Automatic delegate type creation and caching |
|
// |
|
// Author: |
|
// Alexander Corrado (alexander.corrado@gmail.com) |
|
// |
|
// Copyright (C) 2010 Alexander Corrado |
|
// |
|
|
|
using System; |
|
using System.Linq; |
|
using System.Reflection; |
|
using System.Reflection.Emit; |
|
using System.Runtime.InteropServices; |
|
using System.Collections.Generic; |
|
|
|
namespace Mono.VisualC.Interop.Util { |
|
|
|
public static class DelegateTypeCache { |
|
|
|
private static Dictionary<DelegateSignature, Type> type_cache; |
|
|
|
|
|
public static Type GetDelegateType (MethodInfo signature, CallingConvention? callingConvention) |
|
{ |
|
return GetDelegateType (ReflectionHelper.GetMethodParameterTypes (signature), signature.ReturnType, callingConvention); |
|
} |
|
public static Type GetDelegateType (IEnumerable<Type> parameterTypes, Type returnType, CallingConvention? callingConvention) |
|
{ |
|
return GetDelegateType (new DelegateSignature () { ParameterTypes = parameterTypes, ReturnType = returnType, CallingConvention = callingConvention }); |
|
} |
|
public static Type GetDelegateType (DelegateSignature signature) |
|
{ |
|
Type delegateType; |
|
if (type_cache == null) |
|
type_cache = new Dictionary<DelegateSignature, Type> (); |
|
|
|
if (!type_cache.TryGetValue (signature, out delegateType)) { |
|
delegateType = CreateDelegateType (signature); |
|
type_cache.Add (signature, delegateType); |
|
} |
|
|
|
return delegateType; |
|
} |
|
|
|
private static Type CreateDelegateType (DelegateSignature signature) |
|
{ |
|
string delTypeName = signature.UniqueName; |
|
|
|
TypeAttributes typeAttr = TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass; |
|
TypeBuilder del = CppLibrary.interopModule.DefineType (delTypeName, typeAttr, typeof(MulticastDelegate)); |
|
|
|
if (signature.CallingConvention.HasValue) { |
|
ConstructorInfo ufpa = typeof (UnmanagedFunctionPointerAttribute).GetConstructor (new Type [] { typeof (CallingConvention) }); |
|
CustomAttributeBuilder unmanagedPointer = new CustomAttributeBuilder (ufpa, new object [] { signature.CallingConvention.Value }); |
|
del.SetCustomAttribute (unmanagedPointer); |
|
} |
|
|
|
MethodAttributes ctorAttr = MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public; |
|
ConstructorBuilder ctor = del.DefineConstructor (ctorAttr, CallingConventions.Standard, new Type[] { typeof(object), typeof(System.IntPtr) }); |
|
ctor.SetImplementationFlags (MethodImplAttributes.Runtime | MethodImplAttributes.Managed); |
|
|
|
Type [] parameterTypes = signature.ParameterTypes.ToArray (); |
|
MethodAttributes methodAttr = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual; |
|
|
|
MethodBuilder invokeMethod = del.DefineMethod ("Invoke", methodAttr, signature.ReturnType, parameterTypes); |
|
invokeMethod.SetImplementationFlags (MethodImplAttributes.Runtime | MethodImplAttributes.Managed); |
|
|
|
return del.CreateType (); |
|
} |
|
} |
|
|
|
} |
|
|
|
|