Impl progress on c++ name mangling on Clang for proper P/Invokes binding
This commit is contained in:
@@ -18,6 +18,7 @@ namespace Flax.Build.Bindings
|
|||||||
private static readonly List<string> CSharpAdditionalCode = new List<string>();
|
private static readonly List<string> CSharpAdditionalCode = new List<string>();
|
||||||
private static readonly Dictionary<string, string> CSharpAdditionalCodeCache = new Dictionary<string, string>();
|
private static readonly Dictionary<string, string> CSharpAdditionalCodeCache = new Dictionary<string, string>();
|
||||||
#if USE_NETCORE
|
#if USE_NETCORE
|
||||||
|
private static readonly TypeInfo CSharpEventBindReturn = new TypeInfo("void");
|
||||||
private static readonly List<FunctionInfo.ParameterInfo> CSharpEventBindParams = new List<FunctionInfo.ParameterInfo>() { new FunctionInfo.ParameterInfo() { Name = "bind", Type = new TypeInfo("bool") } };
|
private static readonly List<FunctionInfo.ParameterInfo> CSharpEventBindParams = new List<FunctionInfo.ParameterInfo>() { new FunctionInfo.ParameterInfo() { Name = "bind", Type = new TypeInfo("bool") } };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1009,7 +1010,7 @@ namespace Flax.Build.Bindings
|
|||||||
if (buildData.Toolchain.Compiler == TargetCompiler.MSVC)
|
if (buildData.Toolchain.Compiler == TargetCompiler.MSVC)
|
||||||
libraryEntryPoint = $"{classInfo.FullNameManaged}::Internal_{eventInfo.Name}_Bind"; // MSVC allows to override exported symbol name
|
libraryEntryPoint = $"{classInfo.FullNameManaged}::Internal_{eventInfo.Name}_Bind"; // MSVC allows to override exported symbol name
|
||||||
else
|
else
|
||||||
libraryEntryPoint = CppNameMangling.MangleFunctionName(buildData, eventInfo.Name + "_ManagedBind", classInfo.FullNameNativeInternal + "Internal", CSharpEventBindParams);
|
libraryEntryPoint = CppNameMangling.MangleFunctionName(buildData, eventInfo.Name + "_ManagedBind", classInfo.FullNameNativeInternal + "Internal", CSharpEventBindReturn, CSharpEventBindParams);
|
||||||
contents.Append(indent).Append($"[LibraryImport(\"{classInfo.ParentModule.Module.BinaryModuleName}\", EntryPoint = \"{libraryEntryPoint}\", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]").AppendLine();
|
contents.Append(indent).Append($"[LibraryImport(\"{classInfo.ParentModule.Module.BinaryModuleName}\", EntryPoint = \"{libraryEntryPoint}\", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]").AppendLine();
|
||||||
contents.Append(indent).Append($"internal static partial void Internal_{eventInfo.Name}_Bind(");
|
contents.Append(indent).Append($"internal static partial void Internal_{eventInfo.Name}_Bind(");
|
||||||
if (!eventInfo.IsStatic)
|
if (!eventInfo.IsStatic)
|
||||||
|
|||||||
@@ -947,10 +947,7 @@ namespace Flax.Build.Bindings
|
|||||||
{
|
{
|
||||||
Name = "__returnCount",
|
Name = "__returnCount",
|
||||||
DefaultValue = "var __returnCount",
|
DefaultValue = "var __returnCount",
|
||||||
Type = new TypeInfo
|
Type = new TypeInfo("int"),
|
||||||
{
|
|
||||||
Type = "int"
|
|
||||||
},
|
|
||||||
IsOut = true,
|
IsOut = true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -969,7 +966,7 @@ namespace Flax.Build.Bindings
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
libraryEntryPoint = CppNameMangling.MangleFunctionName(buildData, functionInfo.Name, callerName, functionInfo.Parameters, functionInfo.Glue.CustomParameters);
|
libraryEntryPoint = CppNameMangling.MangleFunctionName(buildData, functionInfo.Name, callerName, functionInfo.ReturnType, functionInfo.IsStatic ? null : new TypeInfo(caller.Name) { IsPtr = true }, functionInfo.Parameters, functionInfo.Glue.CustomParameters);
|
||||||
useSeparateImpl = true; // DLLEXPORT doesn't properly export function thus separate implementation from declaration
|
useSeparateImpl = true; // DLLEXPORT doesn't properly export function thus separate implementation from declaration
|
||||||
}
|
}
|
||||||
functionInfo.Glue.LibraryEntryPoint = libraryEntryPoint;
|
functionInfo.Glue.LibraryEntryPoint = libraryEntryPoint;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Text;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Flax.Build.Bindings;
|
using Flax.Build.Bindings;
|
||||||
|
|
||||||
@@ -11,19 +12,30 @@ namespace Flax.Build
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal static class CppNameMangling
|
internal static class CppNameMangling
|
||||||
{
|
{
|
||||||
public static string MangleFunctionName(Builder.BuildData buildData, string name, string outerName, List<FunctionInfo.ParameterInfo> parameters1, List<FunctionInfo.ParameterInfo> parameters2)
|
public static string MangleFunctionName(Builder.BuildData buildData, string name, string outerName, TypeInfo returnType, TypeInfo parameter0, List<FunctionInfo.ParameterInfo> parameters1, List<FunctionInfo.ParameterInfo> parameters2)
|
||||||
{
|
{
|
||||||
if (parameters1 == null || parameters1.Count == 0)
|
List<FunctionInfo.ParameterInfo> parameters = null;
|
||||||
return MangleFunctionName(buildData, name, outerName, parameters2);
|
if (parameter0 == null)
|
||||||
if (parameters2 == null || parameters2.Count == 0)
|
{
|
||||||
return MangleFunctionName(buildData, name, outerName, parameters1);
|
if (parameters1 == null || parameters1.Count == 0)
|
||||||
var parameters = new List<FunctionInfo.ParameterInfo>();
|
parameters = parameters2;
|
||||||
parameters.AddRange(parameters1);
|
else if (parameters2 == null || parameters2.Count == 0)
|
||||||
parameters.AddRange(parameters2);
|
parameters = parameters1;
|
||||||
return MangleFunctionName(buildData, name, outerName, parameters);
|
}
|
||||||
|
if (parameters == null)
|
||||||
|
{
|
||||||
|
parameters = new List<FunctionInfo.ParameterInfo>();
|
||||||
|
if (parameter0 != null)
|
||||||
|
parameters.Add(new FunctionInfo.ParameterInfo() { Type = parameter0 });
|
||||||
|
if (parameters1 != null)
|
||||||
|
parameters.AddRange(parameters1);
|
||||||
|
if (parameters2 != null)
|
||||||
|
parameters.AddRange(parameters2);
|
||||||
|
}
|
||||||
|
return MangleFunctionName(buildData, name, outerName, returnType, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string MangleFunctionName(Builder.BuildData buildData, string name, string outerName, List<FunctionInfo.ParameterInfo> parameters)
|
public static string MangleFunctionName(Builder.BuildData buildData, string name, string outerName, TypeInfo returnType, List<FunctionInfo.ParameterInfo> parameters)
|
||||||
{
|
{
|
||||||
if (name.Contains(":"))
|
if (name.Contains(":"))
|
||||||
throw new NotImplementedException("No nested types mangling support.");
|
throw new NotImplementedException("No nested types mangling support.");
|
||||||
@@ -42,7 +54,28 @@ namespace Flax.Build
|
|||||||
// TODO: mangle parameters
|
// TODO: mangle parameters
|
||||||
break;
|
break;
|
||||||
case TargetCompiler.Clang:
|
case TargetCompiler.Clang:
|
||||||
sb.Append("todo");
|
// References:
|
||||||
|
// http://web.mit.edu/tibbetts/Public/inside-c/www/mangling.html
|
||||||
|
// https://en.wikipedia.org/wiki/Name_mangling
|
||||||
|
sb.Append("_ZN");
|
||||||
|
//if (!returnType.IsVoid)
|
||||||
|
// MangleTypeClang(sb, returnType);
|
||||||
|
sb.Append(outerName.Length);
|
||||||
|
sb.Append(outerName);
|
||||||
|
sb.Append(name.Length);
|
||||||
|
sb.Append(name);
|
||||||
|
sb.Append('E');
|
||||||
|
if (parameters == null || parameters.Count == 0)
|
||||||
|
{
|
||||||
|
sb.Append('v');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var e in parameters)
|
||||||
|
{
|
||||||
|
MangleTypeClang(sb, e.Type);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new InvalidPlatformException(buildData.Platform.Target);
|
throw new InvalidPlatformException(buildData.Platform.Target);
|
||||||
@@ -51,5 +84,54 @@ namespace Flax.Build
|
|||||||
BindingsGenerator.PutStringBuilder(sb);
|
BindingsGenerator.PutStringBuilder(sb);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void MangleTypeClang(StringBuilder sb, TypeInfo type)
|
||||||
|
{
|
||||||
|
if (type.IsPtr)
|
||||||
|
sb.Append('P');
|
||||||
|
if (type.IsRef)
|
||||||
|
sb.Append('R');
|
||||||
|
if (type.IsConst)
|
||||||
|
sb.Append('K');
|
||||||
|
switch (type.Type)
|
||||||
|
{
|
||||||
|
// TODO: use proper typedef extraction from TypedefInfo
|
||||||
|
case "Float2":
|
||||||
|
sb.Append("11Vector2BaseIfE");
|
||||||
|
break;
|
||||||
|
case "Float3":
|
||||||
|
sb.Append("11Vector3BaseIfE");
|
||||||
|
break;
|
||||||
|
case "Float4":
|
||||||
|
sb.Append("11Vector4BaseIfE");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "bool":
|
||||||
|
sb.Append('b');
|
||||||
|
break;
|
||||||
|
case "char":
|
||||||
|
case "int8":
|
||||||
|
sb.Append('c');
|
||||||
|
break;
|
||||||
|
case "int":
|
||||||
|
case "int32":
|
||||||
|
sb.Append('i');
|
||||||
|
break;
|
||||||
|
case "float":
|
||||||
|
sb.Append('f');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sb.Append(type.Type.Length);
|
||||||
|
sb.Append(type.Type);
|
||||||
|
if (type.GenericArgs != null)
|
||||||
|
{
|
||||||
|
sb.Append('I');
|
||||||
|
foreach (var e in type.GenericArgs)
|
||||||
|
MangleTypeClang(sb, e);
|
||||||
|
sb.Append('E');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user