private void SetTypeInfo4(Type type, bool isReturnType, bool isExceptionSafe)
{
// isExceptionSafe determines whether or not exception wrapper will be constructed
// if isExceptionSafe then no exception wrapper is created
// else the wrapper function returns an object, and the XlObjectMarshaler is always
// used - the wrapper then ensures that #ERROR is returned from the function
// if any exception is caught.
// if no exception, the return type is known to be of type BoxedReturnValueType
// and unboxed accordingly.
// NOTE: There is also a list of supported parameter types in
// AssemblyLoaded.cs, where the methods to register are extracted.
// By default DelegateParamType is type
// changed for some return types to ensure boxing,
// to allow custom marshaling.
DelegateParamType = type;
if (type == typeof(double))
{
if (isReturnType && !isExceptionSafe)
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(double);
}
else
{
XlType = "B";
}
}
else if (type == typeof(string))
{
// CONSIDER: Other options for string marshaling (nulls etc??)
if (isReturnType)
{
if (!isExceptionSafe)
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
DelegateParamType = typeof(object);
}
else
{
XlType = "D"; // byte-counted string *
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlStringReturnMarshaler));
}
}
else
{
XlType = "C"; // LPSTR
MarshalAsAttribute = GetMarshalAsAttribute(UnmanagedType.LPStr);
}
}
else if (type == typeof(DateTime))
{
if (isReturnType)
{
if (!isExceptionSafe)
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(DateTime);
}
else
{
// TODO: Consolidate with the above case? - NO! Cluster Connector does not allow OPER types
XlType = "E"; // double*
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlDateTimeMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(DateTime);
}
}
else
{
XlType = "E"; // double*
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlDateTimeMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(DateTime);
}
}
else if (type == typeof(double[]))
{
//if (isReturnType && !isExceptionSafe)
//{
// XlType = 'P'; // OPER
// MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
// DelegateParamType = typeof(object);
//}
//else
//{
XlType = "K"; // FP*
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlDoubleArrayMarshaler), "1");
//}
}
else if (type == typeof(double[,]))
{
//if (isReturnType && !isExceptionSafe)
//{
// XlType = 'P'; // OPER
// MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
// DelegateParamType = typeof(object);
//}
//else
//{
XlType = "K"; // FP*
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlDoubleArrayMarshaler), "2");
//}
}
else if (type == typeof(object))
{
// Before version 0.29 we had:
// if (isReturnType || AllowReference)
// XlType = "U"; // XLOPER
// and thus registered as U in most cases.
// This does not work in HPC setting, and seems to have been a mistake anyway
// - returning a reference always gives #VALUE
if (AllowReference)
XlType = "R"; // XLOPER
else
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
DelegateParamType = typeof(object);
}
else if (type == typeof(object[]))
{
if (isReturnType && !isExceptionSafe)
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
DelegateParamType = typeof(object);
}
else
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectArrayMarshaler), "1");
}
}
else if (type == typeof(object[,]))
{
if (isReturnType && !isExceptionSafe)
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
DelegateParamType = typeof(object);
}
else
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectArrayMarshaler), "2");
}
}
else if (type == typeof(bool))
{
if (isReturnType)
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(bool);
}
else
{
// XlType = "J"; // int32
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlBooleanMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(bool);
}
}
else if (type == typeof(int))
{
if (isReturnType)
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(int);
}
else
{
// XlType = "J";
XlType = "E"; // double*
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlInt32ParameterMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(int);
}
}
else if (type == typeof(short))
{
if (isReturnType)
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(short);
}
else
{
// XlType = "I";
XlType = "E"; // double*
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlInt16ParameterMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(short);
}
}
else if (type == typeof(ushort))
{
if (isReturnType)
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(ushort);
}
else
{
// XlType = "H";
XlType = "E"; // double*
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlUInt16ParameterMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(ushort);
}
}
else if (type == typeof(decimal))
{
if (isReturnType)
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(decimal);
}
else
{
XlType = "E"; // double*
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlDecimalParameterMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(decimal);
}
}
else if (type == typeof(long))
{
// Just like decimal - change to double as well as we can.
if (isReturnType)
{
XlType = "P"; // OPER
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(long);
}
else
{
XlType = "E"; // double*
MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlInt64ParameterMarshaler));
DelegateParamType = typeof(object);
BoxedValueType = typeof(long);
}
}
else
{
// The function is bad and cannot be marshaled to Excel
throw new DnaMarshalException("Unknown Data Type: " + type.ToString());
}
}