Add MarshalAs tag to APi structs/classes for custom marshaling via implicit casting
This commit is contained in:
@@ -22,6 +22,7 @@ namespace Flax.Build.Bindings
|
||||
public string[] Comment;
|
||||
public bool IsInBuild;
|
||||
public bool IsDeprecated;
|
||||
public string MarshalAs;
|
||||
internal bool IsInited;
|
||||
internal TypedefInfo Instigator;
|
||||
|
||||
@@ -151,6 +152,7 @@ namespace Flax.Build.Bindings
|
||||
BindingsGenerator.Write(writer, Namespace);
|
||||
BindingsGenerator.Write(writer, Attributes);
|
||||
BindingsGenerator.Write(writer, Comment);
|
||||
BindingsGenerator.Write(writer, MarshalAs);
|
||||
writer.Write(IsInBuild);
|
||||
writer.Write(IsDeprecated);
|
||||
BindingsGenerator.Write(writer, Tags);
|
||||
@@ -164,6 +166,7 @@ namespace Flax.Build.Bindings
|
||||
Namespace = BindingsGenerator.Read(reader, Namespace);
|
||||
Attributes = BindingsGenerator.Read(reader, Attributes);
|
||||
Comment = BindingsGenerator.Read(reader, Comment);
|
||||
MarshalAs = BindingsGenerator.Read(reader, MarshalAs);
|
||||
IsInBuild = reader.ReadBoolean();
|
||||
IsDeprecated = reader.ReadBoolean();
|
||||
Tags = BindingsGenerator.Read(reader, Tags);
|
||||
|
||||
@@ -196,6 +196,9 @@ namespace Flax.Build.Bindings
|
||||
var apiType = FindApiTypeInfo(buildData, typeInfo, caller);
|
||||
if (apiType != null)
|
||||
{
|
||||
if (apiType.MarshalAs != null)
|
||||
return UsePassByReference(buildData, new TypeInfo(apiType.MarshalAs), caller);
|
||||
|
||||
// Skip for scripting objects
|
||||
if (apiType.IsScriptingObject)
|
||||
return false;
|
||||
|
||||
@@ -420,6 +420,8 @@ namespace Flax.Build.Bindings
|
||||
apiTypeParent = apiTypeParent.Parent;
|
||||
}
|
||||
|
||||
if (apiType.MarshalAs != null)
|
||||
return GenerateCSharpManagedToNativeType(buildData, new TypeInfo(apiType.MarshalAs), caller);
|
||||
if (apiType.IsScriptingObject || apiType.IsInterface)
|
||||
return "IntPtr";
|
||||
}
|
||||
@@ -509,7 +511,11 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
else
|
||||
{
|
||||
returnValueType = GenerateCSharpNativeToManaged(buildData, functionInfo.ReturnType, caller);
|
||||
var apiType = FindApiTypeInfo(buildData, functionInfo.ReturnType, caller);
|
||||
if (apiType != null && apiType.MarshalAs != null)
|
||||
returnValueType = GenerateCSharpNativeToManaged(buildData, new TypeInfo(apiType.MarshalAs), caller);
|
||||
else
|
||||
returnValueType = GenerateCSharpNativeToManaged(buildData, functionInfo.ReturnType, caller);
|
||||
}
|
||||
|
||||
#if USE_NETCORE
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Flax.Build.Bindings
|
||||
partial class BindingsGenerator
|
||||
{
|
||||
private static readonly Dictionary<string, Type> TypeCache = new Dictionary<string, Type>();
|
||||
private const int CacheVersion = 19;
|
||||
private const int CacheVersion = 20;
|
||||
|
||||
internal static void Write(BinaryWriter writer, string e)
|
||||
{
|
||||
|
||||
@@ -582,6 +582,9 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
CppReferencesFiles.Add(apiType.File);
|
||||
|
||||
if (apiType.MarshalAs != null)
|
||||
return GenerateCppWrapperNativeToManaged(buildData, new TypeInfo(apiType.MarshalAs), caller, out type, functionInfo);
|
||||
|
||||
// Scripting Object
|
||||
if (apiType.IsScriptingObject)
|
||||
{
|
||||
@@ -791,6 +794,9 @@ namespace Flax.Build.Bindings
|
||||
|
||||
if (apiType != null)
|
||||
{
|
||||
if (apiType.MarshalAs != null)
|
||||
return GenerateCppWrapperManagedToNative(buildData, new TypeInfo(apiType.MarshalAs), caller, out type, out apiType, functionInfo, out needLocalVariable);
|
||||
|
||||
// Scripting Object (for non-pod types converting only, other API converts managed to unmanaged object in C# wrapper code)
|
||||
if (CppNonPodTypesConvertingGeneration && apiType.IsScriptingObject && typeInfo.IsPtr)
|
||||
{
|
||||
@@ -2370,7 +2376,9 @@ namespace Flax.Build.Bindings
|
||||
CppUsedNonPodTypes.Add(structureInfo);
|
||||
contents.AppendLine(" static MObject* Box(void* ptr)");
|
||||
contents.AppendLine(" {");
|
||||
if (structureInfo.IsPod)
|
||||
if (structureInfo.MarshalAs != null)
|
||||
contents.AppendLine($" MISSING_CODE(\"Boxing native type {structureInfo.Name} as {structureInfo.MarshalAs}\"); return nullptr;"); // TODO: impl this
|
||||
else if (structureInfo.IsPod)
|
||||
contents.AppendLine($" return MCore::Object::Box(ptr, {structureTypeNameNative}::TypeInitializer.GetClass());");
|
||||
else
|
||||
contents.AppendLine($" return MUtils::Box(*({structureTypeNameNative}*)ptr, {structureTypeNameNative}::TypeInitializer.GetClass());");
|
||||
@@ -2379,7 +2387,9 @@ namespace Flax.Build.Bindings
|
||||
// Unboxing structures from managed object to native data
|
||||
contents.AppendLine(" static void Unbox(void* ptr, MObject* managed)");
|
||||
contents.AppendLine(" {");
|
||||
if (structureInfo.IsPod)
|
||||
if (structureInfo.MarshalAs != null)
|
||||
contents.AppendLine($" MISSING_CODE(\"Boxing native type {structureInfo.Name} as {structureInfo.MarshalAs}\");"); // TODO: impl this
|
||||
else if (structureInfo.IsPod)
|
||||
contents.AppendLine($" Platform::MemoryCopy(ptr, MCore::Object::Unbox(managed), sizeof({structureTypeNameNative}));");
|
||||
else
|
||||
contents.AppendLine($" *({structureTypeNameNative}*)ptr = ToNative(*({GenerateCppManagedWrapperName(structureInfo)}*)MCore::Object::Unbox(managed));");
|
||||
@@ -2657,6 +2667,13 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
if (CppUsedNonPodTypesList.Contains(apiType))
|
||||
return;
|
||||
if (apiType is ClassStructInfo classStructInfo)
|
||||
{
|
||||
if (classStructInfo.MarshalAs != null)
|
||||
return;
|
||||
if (classStructInfo.IsTemplate)
|
||||
throw new Exception($"Cannot use template type '{classStructInfo}' as non-POD type for cross-language bindings.");
|
||||
}
|
||||
if (apiType is StructureInfo structureInfo)
|
||||
{
|
||||
// Check all fields (if one of them is also non-POD structure then we need to generate wrappers for them too)
|
||||
@@ -2679,11 +2696,6 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
}
|
||||
}
|
||||
if (apiType is ClassStructInfo classStructInfo)
|
||||
{
|
||||
if (classStructInfo.IsTemplate)
|
||||
throw new Exception($"Cannot use template type '{classStructInfo}' as non-POD type for cross-language bindings.");
|
||||
}
|
||||
CppUsedNonPodTypesList.Add(apiType);
|
||||
}
|
||||
|
||||
|
||||
@@ -628,6 +628,9 @@ namespace Flax.Build.Bindings
|
||||
case "namespace":
|
||||
desc.Namespace = tag.Value;
|
||||
break;
|
||||
case "marshalas":
|
||||
desc.MarshalAs = tag.Value;
|
||||
break;
|
||||
case "tag":
|
||||
ParseTag(ref desc.Tags, tag);
|
||||
break;
|
||||
@@ -1202,6 +1205,9 @@ namespace Flax.Build.Bindings
|
||||
case "namespace":
|
||||
desc.Namespace = tag.Value;
|
||||
break;
|
||||
case "marshalas":
|
||||
desc.MarshalAs = tag.Value;
|
||||
break;
|
||||
case "tag":
|
||||
ParseTag(ref desc.Tags, tag);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user