in SharpGen/Transform/MarshalledElementFactory.cs [26:132]
private void CreateCore(CsMarshalBase csMarshallable)
{
var marshallable = (CppMarshallable) csMarshallable.CppElement;
CsTypeBase publicType = null;
CsTypeBase marshalType = null;
var mappingRule = marshallable.Rule;
var publicTypeName = mappingRule is {MappingType: { } mapType} ? mapType : marshallable.TypeName;
// If CppType is an array, try first to get the binding for this array
if (csMarshallable.IsArray)
{
publicType = TypeRegistry.FindBoundType(publicTypeName + "[" + marshallable.ArrayDimension + "]");
if (publicType != null)
csMarshallable.IsArray = false;
}
if (publicType == null)
{
void AssignStringTypes(CsFundamentalType charType)
{
publicType = csMarshallable.HasPointer || csMarshallable.IsArray
? TypeRegistry.String
: charType;
marshalType = csMarshallable.IsArray ? charType : null;
}
switch (publicTypeName)
{
case "char":
AssignStringTypes(TypeRegistry.UInt8);
break;
case "wchar_t":
csMarshallable.IsWideChar = true;
AssignStringTypes(TypeRegistry.Char);
break;
default:
// Try to get a declared type
if (!TypeRegistry.FindBoundType(publicTypeName, out var boundType))
{
Logger.Fatal("Unknown type found [{0}]", publicTypeName);
return;
}
publicType = boundType.CSharpType;
// By default, use the underlying native type as the marshal type
// if it differs from the public type.
marshalType = TypeRegistry.FindBoundType(marshallable.TypeName);
if (publicType == marshalType)
marshalType = null;
// Otherwise, get the registered marshal type if one exists
marshalType ??= boundType.MarshalType;
break;
}
}
switch (publicType)
{
case CsStruct csStruct:
{
if (!csStruct.IsFullyMapped)
// If a structure was not already parsed, then parse it before going further
RequestStructProcessing?.Invoke(csStruct);
if (!csStruct.IsFullyMapped)
// No one tried to map the struct so we can't continue.
Logger.Fatal(
$"No struct processor processed {csStruct.QualifiedName}. Cannot continue processing"
);
if (csStruct.HasMarshalType && !csMarshallable.HasPointer)
// If referenced structure has a specialized marshalling, then use the structure's built-in marshalling
marshalType = publicType;
break;
}
case CsEnum:
// enums don't need a marshal type. They can always marshal as their underlying type.
marshalType = null;
break;
}
if (publicType.IsWellKnownType(GlobalNamespace, WellKnownName.PointerSize))
marshalType = PointerType(mappingRule);
// Present void* elements as IntPtr. Marshal strings as IntPtr
if (marshallable.HasPointer)
{
if (publicType == TypeRegistry.Void)
publicType = marshalType = PointerType(mappingRule);
else if (publicType == TypeRegistry.String)
marshalType = TypeRegistry.IntPtr;
}
csMarshallable.PublicType = publicType;
csMarshallable.MarshalType = marshalType;
csMarshallable.Relations = RelationParser.ParseRelation(mappingRule.Relation, Logger);
}