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 Dictionary<string, string> CSharpAdditionalCodeCache = new Dictionary<string, string>();
|
||||
#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") } };
|
||||
#endif
|
||||
|
||||
@@ -1009,7 +1010,7 @@ namespace Flax.Build.Bindings
|
||||
if (buildData.Toolchain.Compiler == TargetCompiler.MSVC)
|
||||
libraryEntryPoint = $"{classInfo.FullNameManaged}::Internal_{eventInfo.Name}_Bind"; // MSVC allows to override exported symbol name
|
||||
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($"internal static partial void Internal_{eventInfo.Name}_Bind(");
|
||||
if (!eventInfo.IsStatic)
|
||||
|
||||
@@ -947,10 +947,7 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
Name = "__returnCount",
|
||||
DefaultValue = "var __returnCount",
|
||||
Type = new TypeInfo
|
||||
{
|
||||
Type = "int"
|
||||
},
|
||||
Type = new TypeInfo("int"),
|
||||
IsOut = true,
|
||||
});
|
||||
}
|
||||
@@ -969,7 +966,7 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
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
|
||||
}
|
||||
functionInfo.Glue.LibraryEntryPoint = libraryEntryPoint;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using Flax.Build.Bindings;
|
||||
|
||||
@@ -11,19 +12,30 @@ namespace Flax.Build
|
||||
/// </summary>
|
||||
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)
|
||||
return MangleFunctionName(buildData, name, outerName, parameters2);
|
||||
if (parameters2 == null || parameters2.Count == 0)
|
||||
return MangleFunctionName(buildData, name, outerName, parameters1);
|
||||
var parameters = new List<FunctionInfo.ParameterInfo>();
|
||||
parameters.AddRange(parameters1);
|
||||
parameters.AddRange(parameters2);
|
||||
return MangleFunctionName(buildData, name, outerName, parameters);
|
||||
List<FunctionInfo.ParameterInfo> parameters = null;
|
||||
if (parameter0 == null)
|
||||
{
|
||||
if (parameters1 == null || parameters1.Count == 0)
|
||||
parameters = parameters2;
|
||||
else if (parameters2 == null || parameters2.Count == 0)
|
||||
parameters = parameters1;
|
||||
}
|
||||
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(":"))
|
||||
throw new NotImplementedException("No nested types mangling support.");
|
||||
@@ -42,7 +54,28 @@ namespace Flax.Build
|
||||
// TODO: mangle parameters
|
||||
break;
|
||||
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;
|
||||
default:
|
||||
throw new InvalidPlatformException(buildData.Platform.Target);
|
||||
@@ -51,5 +84,54 @@ namespace Flax.Build
|
||||
BindingsGenerator.PutStringBuilder(sb);
|
||||
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