Type CreateDelegateType(ModuleBuilder modBuilder)
{
TypeBuilder typeBuilder;
MethodBuilder methodBuilder;
XlParameterInfo[] paramInfos = Parameters;
Type[] paramTypes = Array.ConvertAll<XlParameterInfo, Type>(paramInfos,
delegate(XlParameterInfo pi)
{ return pi.DelegateParamType; });
// Create a delegate that has the same signature as the method we would like to hook up to
typeBuilder = modBuilder.DefineType("f" + Index++ + "Delegate",
TypeAttributes.Class | TypeAttributes.Public |
TypeAttributes.Sealed,
typeof (System.MulticastDelegate));
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(
MethodAttributes.RTSpecialName | MethodAttributes.HideBySig |
MethodAttributes.Public, CallingConventions.Standard,
new Type[] {typeof (object), typeof (int)});
constructorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime |
MethodImplAttributes.Managed);
// Build up the delegate
// Define the Invoke method for the delegate
methodBuilder = typeBuilder.DefineMethod("Invoke",
MethodAttributes.Public | MethodAttributes.HideBySig |
MethodAttributes.NewSlot | MethodAttributes.Virtual,
HasReturnType ? ReturnType.DelegateParamType : typeof(void),
// What here for macro? null or Void ?
paramTypes);
methodBuilder.SetImplementationFlags(MethodImplAttributes.Runtime |
MethodImplAttributes.Managed);
// Set Marshal Attributes for return type
if (HasReturnType && ReturnType.MarshalAsAttribute != null)
{
ParameterBuilder pb = methodBuilder.DefineParameter(0, ParameterAttributes.None, null);
pb.SetCustomAttribute(ReturnType.MarshalAsAttribute);
}
// ... and the parameters
for (int i = 1; i <= paramInfos.Length; i++)
{
CustomAttributeBuilder b = paramInfos[i - 1].MarshalAsAttribute;
if (b != null)
{
ParameterBuilder pb = methodBuilder.DefineParameter(i, ParameterAttributes.None, null);
pb.SetCustomAttribute(b);
}
}
// Bake the type and get the delegate
return typeBuilder.CreateType();
}