зеркало из https://github.com/mono/CppSharp.git
Refactor code
This commit is contained in:
Родитель
060afd53fc
Коммит
ed278fc636
|
@ -26,39 +26,24 @@ namespace CppSharp.Generators.CSharp
|
|||
{
|
||||
using (WriteBlock($"internal class {@class}"))
|
||||
{
|
||||
GenerateStaticVariables();
|
||||
foreach (var (_, variableIdentifier) in symbols)
|
||||
WriteLine($"public static IntPtr {variableIdentifier} {{ get; }}");
|
||||
|
||||
using (WriteBlock($"static {@class}()"))
|
||||
GenerateStaticConstructorBody();
|
||||
{
|
||||
WriteLine($"var path = \"{path}\";");
|
||||
WriteLine("var image = CppSharp.SymbolResolver.LoadImage(ref path);");
|
||||
WriteLine("if (image == IntPtr.Zero) throw new global::System.DllNotFoundException(path);");
|
||||
|
||||
foreach (var (mangled, variableIdentifier) in symbols)
|
||||
WriteLine($"{variableIdentifier} = CppSharp.SymbolResolver.ResolveSymbol(image, \"{mangled}\");");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ToString();
|
||||
}
|
||||
|
||||
public void GenerateStaticVariables()
|
||||
{
|
||||
foreach (var symbol in symbols)
|
||||
{
|
||||
var variableIdentifier = symbol.Value;
|
||||
WriteLine($"public static IntPtr {variableIdentifier} {{ get; }}");
|
||||
}
|
||||
}
|
||||
|
||||
public void GenerateStaticConstructorBody()
|
||||
{
|
||||
WriteLine($"var path = \"{path}\";");
|
||||
WriteLine("var image = CppSharp.SymbolResolver.LoadImage(ref path);");
|
||||
WriteLine("if (image == IntPtr.Zero) throw new global::System.DllNotFoundException(path);");
|
||||
|
||||
foreach (var symbol in symbols)
|
||||
{
|
||||
var mangled = symbol.Key;
|
||||
var variableIdentifier = symbol.Value;
|
||||
WriteLine($"{variableIdentifier} = CppSharp.SymbolResolver.ResolveSymbol(image, \"{mangled}\");");
|
||||
}
|
||||
}
|
||||
|
||||
public string GetFullVariablePath(string mangled)
|
||||
{
|
||||
return $"global::{@namespace}.{@class}." + GenerateUniqueVariableIdentifier(mangled);
|
||||
|
|
|
@ -246,45 +246,37 @@ namespace CppSharp.Generators.CSharp
|
|||
if (!context.Functions.Any(f => f.IsGenerated) && !hasGlobalVariables)
|
||||
return;
|
||||
|
||||
PushBlock(BlockKind.Functions);
|
||||
var parentName = SafeIdentifier(context.TranslationUnit.FileNameWithoutExtension);
|
||||
var isStruct = EnumerateClasses()
|
||||
.ToList()
|
||||
.FindAll(cls => cls.IsValueType && cls.Name == parentName && context.QualifiedLogicalName == cls.Namespace.QualifiedLogicalName)
|
||||
.Any();
|
||||
|
||||
var keyword = "class";
|
||||
var classes = EnumerateClasses().ToList();
|
||||
if (classes.FindAll(cls => cls.IsValueType && cls.Name == parentName && context.QualifiedLogicalName == cls.Namespace.QualifiedLogicalName).Any())
|
||||
keyword = "struct";
|
||||
WriteLine($"public unsafe partial {keyword} {parentName}");
|
||||
WriteOpenBraceAndIndent();
|
||||
|
||||
PushBlock(BlockKind.InternalsClass);
|
||||
GenerateClassInternalHead(new Class { Name = parentName });
|
||||
WriteOpenBraceAndIndent();
|
||||
|
||||
// Generate all the internal function declarations.
|
||||
foreach (var function in context.Functions)
|
||||
using (PushWriteBlock(BlockKind.Functions, $"public unsafe partial {(isStruct ? "struct" : "class")} {parentName}", NewLineKind.BeforeNextBlock))
|
||||
{
|
||||
if ((!function.IsGenerated && !function.IsInternal) || function.IsSynthetized)
|
||||
continue;
|
||||
using (PushWriteBlock(BlockKind.InternalsClass, GetClassInternalHead(new Class { Name = parentName }), NewLineKind.BeforeNextBlock))
|
||||
{
|
||||
// Generate all the internal function declarations.
|
||||
foreach (var function in context.Functions)
|
||||
{
|
||||
if ((!function.IsGenerated && !function.IsInternal) || function.IsSynthetized)
|
||||
continue;
|
||||
|
||||
GenerateInternalFunction(function);
|
||||
GenerateInternalFunction(function);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var function in context.Functions)
|
||||
{
|
||||
if (!function.IsGenerated) continue;
|
||||
|
||||
GenerateFunction(function, parentName);
|
||||
}
|
||||
|
||||
foreach (var variable in context.Variables.Where(
|
||||
v => v.IsGenerated && v.Access == AccessSpecifier.Public))
|
||||
GenerateVariable(null, variable);
|
||||
}
|
||||
|
||||
UnindentAndWriteCloseBrace();
|
||||
PopBlock(NewLineKind.BeforeNextBlock);
|
||||
|
||||
foreach (var function in context.Functions)
|
||||
{
|
||||
if (!function.IsGenerated) continue;
|
||||
|
||||
GenerateFunction(function, parentName);
|
||||
}
|
||||
|
||||
foreach (var variable in context.Variables.Where(
|
||||
v => v.IsGenerated && v.Access == AccessSpecifier.Public))
|
||||
GenerateVariable(null, variable);
|
||||
|
||||
UnindentAndWriteCloseBrace();
|
||||
PopBlock(NewLineKind.BeforeNextBlock);
|
||||
}
|
||||
|
||||
private void GenerateClassTemplateSpecializationInternal(Class classTemplate)
|
||||
|
@ -304,25 +296,28 @@ namespace CppSharp.Generators.CSharp
|
|||
!template.OriginalNamespace.IsDependent ?
|
||||
template.OriginalNamespace.Name + '_' : string.Empty,
|
||||
template.Name);
|
||||
using var _ = PushWriteBlock(BlockKind.Namespace, namespaceName, NewLineKind.BeforeNextBlock);
|
||||
var generated = GetGeneratedClasses(template, specializations);
|
||||
|
||||
foreach (var nestedTemplate in template.Classes.Where(
|
||||
c => c.IsDependent && !c.Ignore && c.Specializations.Any(s => !s.Ignore)))
|
||||
GenerateClassTemplateSpecializationsInternals(
|
||||
nestedTemplate, nestedTemplate.Specializations);
|
||||
|
||||
if (template.HasDependentValueFieldInLayout(specializations) ||
|
||||
template.Specializations.Intersect(specializations).Count() == specializations.Count)
|
||||
foreach (var specialization in generated)
|
||||
GenerateClassInternals(specialization);
|
||||
|
||||
foreach (var group in specializations.SelectMany(s => s.Classes).Where(
|
||||
c => !c.IsIncomplete).GroupBy(c => c.Name))
|
||||
using (PushWriteBlock(BlockKind.Namespace, namespaceName, NewLineKind.BeforeNextBlock))
|
||||
{
|
||||
var nested = template.Classes.FirstOrDefault(c => c.Name == group.Key);
|
||||
if (nested != null)
|
||||
GenerateNestedInternals(group.Key, GetGeneratedClasses(nested, group));
|
||||
var generated = GetGeneratedClasses(template, specializations);
|
||||
|
||||
foreach (var nestedTemplate in template.Classes.Where(
|
||||
c => c.IsDependent && !c.Ignore && c.Specializations.Any(s => !s.Ignore)))
|
||||
GenerateClassTemplateSpecializationsInternals(
|
||||
nestedTemplate, nestedTemplate.Specializations);
|
||||
|
||||
if (template.HasDependentValueFieldInLayout(specializations) ||
|
||||
template.Specializations.Intersect(specializations).Count() == specializations.Count)
|
||||
foreach (var specialization in generated)
|
||||
GenerateClassInternals(specialization);
|
||||
|
||||
foreach (var group in specializations.SelectMany(s => s.Classes).Where(
|
||||
c => !c.IsIncomplete).GroupBy(c => c.Name))
|
||||
{
|
||||
var nested = template.Classes.FirstOrDefault(c => c.Name == group.Key);
|
||||
if (nested != null)
|
||||
GenerateNestedInternals(group.Key, GetGeneratedClasses(nested, group));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,72 +409,24 @@ namespace CppSharp.Generators.CSharp
|
|||
PushBlock(BlockKind.Field);
|
||||
if (@class.IsValueType)
|
||||
{
|
||||
WriteLine("private {0}.{1} {2};", @class.Name, Helpers.InternalStruct,
|
||||
Helpers.InstanceField);
|
||||
WriteLine("internal {0}.{1} {2} {{ get {{ return {3}; }} }}", @class.Name,
|
||||
Helpers.InternalStruct, Helpers.InstanceIdentifier, Helpers.InstanceField);
|
||||
WriteLine($"private {@class.Name}.{Helpers.InternalStruct} {Helpers.InstanceField};");
|
||||
WriteLine($"internal {@class.Name}.{Helpers.InternalStruct} {Helpers.InstanceIdentifier} => {Helpers.InstanceField};");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine("public {0} {1} {{ get; protected set; }}",
|
||||
TypePrinter.IntPtrType, Helpers.InstanceIdentifier);
|
||||
|
||||
PopBlock(NewLineKind.BeforeNextBlock);
|
||||
|
||||
PushBlock(BlockKind.Field);
|
||||
|
||||
WriteLine($"public {TypePrinter.IntPtrType} {Helpers.InstanceIdentifier} {{ get; protected set; }}");
|
||||
if (@class.Layout.HasSubclassAtNonZeroOffset)
|
||||
WriteLine($"protected int {Helpers.PrimaryBaseOffsetIdentifier};");
|
||||
|
||||
// use interfaces if any - derived types with a secondary base this class must be compatible with the map
|
||||
var @interface = @class.Namespace.Classes.FirstOrDefault(
|
||||
c => c.IsInterface && c.OriginalClass == @class);
|
||||
var printedClass = (@interface ?? @class).Visit(TypePrinter);
|
||||
var valueType = Options.GenerateFinalizerFor(@class) ? $"global::System.WeakReference<{printedClass}>" : $"{printedClass}";
|
||||
var dict = $@"global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, {valueType}>";
|
||||
|
||||
var generateNativeToManaged = Options.GenerateNativeToManagedFor(@class);
|
||||
if (generateNativeToManaged)
|
||||
WriteLine("internal static readonly {0} NativeToManagedMap = new {0}();", dict);
|
||||
PopBlock(NewLineKind.BeforeNextBlock);
|
||||
|
||||
// Create a method to record/recover a mapping to make it easier to call from template instantiation
|
||||
// implementations. If finalizers are in play, use weak references; otherwise, the finalizer
|
||||
// will never get invoked: unless the managed object is Disposed, there will always be a reference
|
||||
// in the dictionary.
|
||||
PushBlock(BlockKind.Method);
|
||||
if (generateNativeToManaged)
|
||||
{
|
||||
if (Options.GenerateFinalizerFor(@class))
|
||||
{
|
||||
WriteLines($@"
|
||||
internal static void {Helpers.RecordNativeToManagedMappingIdentifier}(IntPtr native, {printedClass} managed)
|
||||
{{
|
||||
NativeToManagedMap[native] = new global::System.WeakReference<{printedClass}>(managed);
|
||||
}}
|
||||
|
||||
internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr native, out {printedClass} managed)
|
||||
{{
|
||||
managed = default;
|
||||
return NativeToManagedMap.TryGetValue(native, out var wr) && wr.TryGetTarget(out managed);
|
||||
}}");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLines($@"
|
||||
internal static void {Helpers.RecordNativeToManagedMappingIdentifier}(IntPtr native, {printedClass} managed)
|
||||
{{
|
||||
NativeToManagedMap[native] = managed;
|
||||
}}
|
||||
|
||||
internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr native, out {printedClass} managed)
|
||||
{{
|
||||
return NativeToManagedMap.TryGetValue(native, out managed);
|
||||
}}");
|
||||
}
|
||||
}
|
||||
}
|
||||
PopBlock(NewLineKind.BeforeNextBlock);
|
||||
|
||||
if (!@class.IsValueType)
|
||||
{
|
||||
PushBlock(BlockKind.Method);
|
||||
if (Options.GenerateNativeToManagedFor(@class))
|
||||
GenerateNativeToManaged(@class);
|
||||
PopBlock(NewLineKind.BeforeNextBlock);
|
||||
}
|
||||
}
|
||||
|
||||
// Add booleans to track who owns unmanaged memory for string fields
|
||||
|
@ -506,6 +453,40 @@ namespace CppSharp.Generators.CSharp
|
|||
return true;
|
||||
}
|
||||
|
||||
public void GenerateNativeToManaged(Class @class)
|
||||
{
|
||||
// use interfaces if any - derived types with a secondary base this class must be compatible with the map
|
||||
var @interface = @class.Namespace.Classes.FirstOrDefault(c => c.IsInterface && c.OriginalClass == @class);
|
||||
var printedClass = (@interface ?? @class).Visit(TypePrinter);
|
||||
|
||||
// Create a method to record/recover a mapping to make it easier to call from template instantiation
|
||||
// implementations. If finalizers are in play, use weak references; otherwise, the finalizer
|
||||
// will never get invoked: unless the managed object is Disposed, there will always be a reference
|
||||
// in the dictionary.
|
||||
|
||||
bool generateFinalizer = Options.GenerateFinalizerFor(@class);
|
||||
var type = generateFinalizer ? $"global::System.WeakReference<{printedClass}>" : $"{printedClass}";
|
||||
|
||||
WriteLines($@"
|
||||
internal static readonly new global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, {type}> NativeToManagedMap =
|
||||
new global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, {type}>();
|
||||
|
||||
internal static void {Helpers.RecordNativeToManagedMappingIdentifier}(IntPtr native, {printedClass} managed)
|
||||
{{
|
||||
NativeToManagedMap[native] = {(generateFinalizer ? $"new {type}(managed)" : "managed")};
|
||||
}}
|
||||
|
||||
internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr native, out {printedClass} managed)
|
||||
{{
|
||||
{(generateFinalizer
|
||||
? @"
|
||||
managed = default;
|
||||
return NativeToManagedMap.TryGetValue(native, out var wr) && wr.TryGetTarget(out managed);"
|
||||
: @"
|
||||
return NativeToManagedMap.TryGetValue(native, out managed);")}
|
||||
}}");
|
||||
}
|
||||
|
||||
private void GenerateInterface(Class @class)
|
||||
{
|
||||
if (!@class.IsGenerated || @class.IsIncomplete)
|
||||
|
@ -577,8 +558,6 @@ namespace CppSharp.Generators.CSharp
|
|||
{
|
||||
var sequentialLayout = Options.GenerateSequentialLayout && CanUseSequentialLayout(@class);
|
||||
|
||||
PushBlock(BlockKind.InternalsClass);
|
||||
|
||||
if (@class.Layout.Size > 0)
|
||||
{
|
||||
var layout = sequentialLayout ? "Sequential" : "Explicit";
|
||||
|
@ -586,25 +565,22 @@ namespace CppSharp.Generators.CSharp
|
|||
WriteLine($"[StructLayout(LayoutKind.{layout}, Size = {@class.Layout.Size}{pack})]");
|
||||
}
|
||||
|
||||
GenerateClassInternalHead(@class);
|
||||
WriteOpenBraceAndIndent();
|
||||
|
||||
TypePrinter.PushContext(TypePrinterContextKind.Native);
|
||||
|
||||
GenerateClassInternalsFields(@class, sequentialLayout);
|
||||
|
||||
if (@class.IsGenerated)
|
||||
using (PushWriteBlock(BlockKind.InternalsClass, GetClassInternalHead(@class), NewLineKind.BeforeNextBlock))
|
||||
{
|
||||
var functions = GatherClassInternalFunctions(@class);
|
||||
TypePrinter.PushContext(TypePrinterContextKind.Native);
|
||||
|
||||
foreach (var function in functions)
|
||||
GenerateInternalFunction(function);
|
||||
GenerateClassInternalsFields(@class, sequentialLayout);
|
||||
|
||||
if (@class.IsGenerated)
|
||||
{
|
||||
var functions = GatherClassInternalFunctions(@class);
|
||||
|
||||
foreach (var function in functions)
|
||||
GenerateInternalFunction(function);
|
||||
}
|
||||
|
||||
TypePrinter.PopContext();
|
||||
}
|
||||
|
||||
TypePrinter.PopContext();
|
||||
|
||||
UnindentAndWriteCloseBrace();
|
||||
PopBlock(NewLineKind.BeforeNextBlock);
|
||||
}
|
||||
|
||||
private IEnumerable<Function> GatherClassInternalFunctions(Class @class,
|
||||
|
@ -725,10 +701,8 @@ namespace CppSharp.Generators.CSharp
|
|||
return @params;
|
||||
}
|
||||
|
||||
private void GenerateClassInternalHead(Class @class)
|
||||
private string GetClassInternalHead(Class @class)
|
||||
{
|
||||
Write("public ");
|
||||
|
||||
bool isSpecialization = false;
|
||||
DeclarationContext declContext = @class;
|
||||
while (declContext != null)
|
||||
|
@ -738,12 +712,10 @@ namespace CppSharp.Generators.CSharp
|
|||
break;
|
||||
declContext = declContext.Namespace;
|
||||
}
|
||||
if (@class != null && @class.NeedsBase &&
|
||||
!@class.BaseClass.IsInterface && !(@class.BaseClass is ClassTemplateSpecialization) && !isSpecialization)
|
||||
Write("new ");
|
||||
var @new = @class != null && @class.NeedsBase &&
|
||||
!@class.BaseClass.IsInterface && !(@class.BaseClass is ClassTemplateSpecialization) && !isSpecialization;
|
||||
|
||||
WriteLine($@"{(isSpecialization ? "unsafe " : string.Empty)}partial struct {
|
||||
Helpers.InternalStruct}{Helpers.GetSuffixForInternal(@class)}");
|
||||
return $@"public {(@new ? "new " : "")}{(isSpecialization ? "unsafe " : string.Empty)}partial struct {Helpers.InternalStruct}{Helpers.GetSuffixForInternal(@class)}";
|
||||
}
|
||||
|
||||
public static bool ShouldGenerateClassNativeField(Class @class)
|
||||
|
@ -974,8 +946,7 @@ namespace CppSharp.Generators.CSharp
|
|||
if (ctx.HasCodeBlock)
|
||||
Indent();
|
||||
|
||||
WriteLine($@"*{ptr} = {marshal.Context.ArgumentPrefix}{
|
||||
marshal.Context.Return};", marshal.Context.Return);
|
||||
WriteLine($@"*{ptr} = {marshal.Context.ArgumentPrefix}{marshal.Context.Return};", marshal.Context.Return);
|
||||
|
||||
if (ctx.HasCodeBlock)
|
||||
UnindentAndWriteCloseBrace();
|
||||
|
@ -1020,10 +991,7 @@ namespace CppSharp.Generators.CSharp
|
|||
var actualProperty = GetActualProperty(property, @class);
|
||||
if (actualProperty == null)
|
||||
{
|
||||
WriteLine($@"throw new MissingMethodException(""Method {
|
||||
property.Name} missing from explicit specialization {
|
||||
@class.Visit(TypePrinter)}."");");
|
||||
|
||||
WriteLine($@"throw new MissingMethodException(""Method {property.Name} missing from explicit specialization {@class.Visit(TypePrinter)}."");");
|
||||
return false;
|
||||
}
|
||||
property = actualProperty;
|
||||
|
@ -1178,8 +1146,7 @@ namespace CppSharp.Generators.CSharp
|
|||
var internalFunction = GetFunctionNativeIdentifier(function);
|
||||
var paramMarshal = GenerateFunctionParamMarshal(
|
||||
function.Parameters[0], 0);
|
||||
string call = $@"{@internal}.{internalFunction}({
|
||||
GetInstanceParam(function)}, {paramMarshal.Context.ArgumentPrefix}{paramMarshal.Name})";
|
||||
string call = $@"{@internal}.{internalFunction}({GetInstanceParam(function)}, {paramMarshal.Context.ArgumentPrefix}{paramMarshal.Name})";
|
||||
if (type.IsPrimitiveType())
|
||||
{
|
||||
WriteLine($"*{call} = {marshal.Context.ArgumentPrefix}{marshal.Context.Return};");
|
||||
|
@ -1190,13 +1157,11 @@ namespace CppSharp.Generators.CSharp
|
|||
if (type.TryGetClass(out @class) && @class.HasNonTrivialCopyConstructor)
|
||||
{
|
||||
Method cctor = @class.Methods.First(c => c.IsCopyConstructor);
|
||||
WriteLine($@"{TypePrinter.PrintNative(type)}.{
|
||||
GetFunctionNativeIdentifier(cctor)}({call}, {marshal.Context.Return});");
|
||||
WriteLine($@"{TypePrinter.PrintNative(type)}.{GetFunctionNativeIdentifier(cctor)}({call}, {marshal.Context.Return});");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine($@"*({TypePrinter.PrintNative(type)}*) {call} = {
|
||||
marshal.Context.ArgumentPrefix}{marshal.Context.Return};");
|
||||
WriteLine($@"*({TypePrinter.PrintNative(type)}*) {call} = {marshal.Context.ArgumentPrefix}{marshal.Context.Return};");
|
||||
}
|
||||
}
|
||||
if (paramMarshal.HasUsingBlock)
|
||||
|
@ -1329,9 +1294,7 @@ namespace CppSharp.Generators.CSharp
|
|||
arrayType.SizeType == ArrayType.ArraySize.Constant)
|
||||
ctx.ReturnVarName = ptr;
|
||||
else
|
||||
ctx.ReturnVarName = $@"{elementType}.{
|
||||
Helpers.CreateInstanceIdentifier}(new {
|
||||
TypePrinter.IntPtrType}({ptr}))";
|
||||
ctx.ReturnVarName = $@"{elementType}.{Helpers.CreateInstanceIdentifier}(new {TypePrinter.IntPtrType}({ptr}))";
|
||||
|
||||
var marshal = new CSharpMarshalNativeToManagedPrinter(ctx);
|
||||
var.QualifiedType.Visit(marshal);
|
||||
|
@ -1355,10 +1318,7 @@ namespace CppSharp.Generators.CSharp
|
|||
var actualProperty = GetActualProperty(property, @class);
|
||||
if (actualProperty == null)
|
||||
{
|
||||
WriteLine($@"throw new MissingMethodException(""Method {
|
||||
property.Name} missing from explicit specialization {
|
||||
@class.Visit(TypePrinter)}."");");
|
||||
|
||||
WriteLine($@"throw new MissingMethodException(""Method {property.Name} missing from explicit specialization {@class.Visit(TypePrinter)}."");");
|
||||
return false;
|
||||
}
|
||||
QualifiedType type = default;
|
||||
|
@ -1601,8 +1561,7 @@ namespace CppSharp.Generators.CSharp
|
|||
}
|
||||
else
|
||||
{
|
||||
WriteLine($@"{printedType} {
|
||||
prop.ExplicitInterfaceImpl.Name}.{GetPropertyName(prop)}");
|
||||
WriteLine($@"{printedType} {prop.ExplicitInterfaceImpl.Name}.{GetPropertyName(prop)}");
|
||||
}
|
||||
WriteOpenBraceAndIndent();
|
||||
|
||||
|
@ -1659,16 +1618,14 @@ namespace CppSharp.Generators.CSharp
|
|||
GeneratePropertyGetterForVariableWithInitializer(variable, signature);
|
||||
else
|
||||
{
|
||||
WriteLine(signature);
|
||||
WriteOpenBraceAndIndent();
|
||||
using (WriteBlock(signature))
|
||||
{
|
||||
GeneratePropertyGetter(variable, @class);
|
||||
|
||||
GeneratePropertyGetter(variable, @class);
|
||||
|
||||
if (!variable.QualifiedType.Qualifiers.IsConst &&
|
||||
!(variable.Type.Desugar() is ArrayType))
|
||||
GeneratePropertySetter(variable, @class);
|
||||
|
||||
UnindentAndWriteCloseBrace();
|
||||
if (!variable.QualifiedType.Qualifiers.IsConst &&
|
||||
!(variable.Type.Desugar() is ArrayType))
|
||||
GeneratePropertySetter(variable, @class);
|
||||
}
|
||||
}
|
||||
|
||||
PopBlock(NewLineKind.BeforeNextBlock);
|
||||
|
@ -1712,22 +1669,20 @@ namespace CppSharp.Generators.CSharp
|
|||
var originalTableClass = @class.IsDependent ? @class.Specializations[0] : @class;
|
||||
var destructorOnly = "destructorOnly";
|
||||
|
||||
WriteLine($"internal static{(hasDynamicBase ? " new" : string.Empty)} class VTableLoader");
|
||||
using (WriteBlock($"internal static{(hasDynamicBase ? " new" : string.Empty)} class VTableLoader"))
|
||||
{
|
||||
WriteOpenBraceAndIndent();
|
||||
WriteLine($"private static volatile bool initialized;");
|
||||
WriteLine($"private static readonly IntPtr*[] ManagedVTables = new IntPtr*[{@class.Layout.VTablePointers.Count}];");
|
||||
if (hasVirtualDtor)
|
||||
WriteLine($"private static readonly IntPtr*[] ManagedVTablesDtorOnly = new IntPtr*[{@class.Layout.VTablePointers.Count}];");
|
||||
WriteLine($"private static readonly IntPtr[] Thunks = new IntPtr[{wrappedEntries.Count}];");
|
||||
WriteLine("private static CppSharp.Runtime.VTables VTables;");
|
||||
WriteLine($"private static readonly global::System.Collections.Generic.List<CppSharp.Runtime.SafeUnmanagedMemoryHandle>");
|
||||
WriteLineIndent("SafeHandles = new global::System.Collections.Generic.List<CppSharp.Runtime.SafeUnmanagedMemoryHandle>();");
|
||||
NewLine();
|
||||
WriteLines($@"
|
||||
private static volatile bool initialized;
|
||||
private static readonly IntPtr*[] ManagedVTables = new IntPtr*[{@class.Layout.VTablePointers.Count}];{(hasVirtualDtor ? $@"
|
||||
private static readonly IntPtr*[] ManagedVTablesDtorOnly = new IntPtr*[{@class.Layout.VTablePointers.Count}];" : "")}
|
||||
private static readonly IntPtr[] Thunks = new IntPtr[{wrappedEntries.Count}];
|
||||
private static CppSharp.Runtime.VTables VTables;
|
||||
private static readonly global::System.Collections.Generic.List<CppSharp.Runtime.SafeUnmanagedMemoryHandle>
|
||||
SafeHandles = new global::System.Collections.Generic.List<CppSharp.Runtime.SafeUnmanagedMemoryHandle>();
|
||||
", trimIndentation: true);
|
||||
|
||||
WriteLine($"static VTableLoader()");
|
||||
using (WriteBlock($"static VTableLoader()"))
|
||||
{
|
||||
WriteOpenBraceAndIndent();
|
||||
foreach (var entry in wrappedEntries.Distinct().Where(e => !e.Method.Ignore))
|
||||
{
|
||||
var name = GetVTableMethodDelegateName(entry.Method);
|
||||
|
@ -1742,13 +1697,11 @@ namespace CppSharp.Generators.CSharp
|
|||
WriteLine($"Thunks[{i}] = Marshal.GetFunctionPointerForDelegate({name + "Instance"});");
|
||||
}
|
||||
}
|
||||
UnindentAndWriteCloseBrace();
|
||||
}
|
||||
NewLine();
|
||||
|
||||
WriteLine($"public static CppSharp.Runtime.VTables SetupVTables(IntPtr instance, bool {destructorOnly} = false)");
|
||||
using (WriteBlock($"public static CppSharp.Runtime.VTables SetupVTables(IntPtr instance, bool {destructorOnly} = false)"))
|
||||
{
|
||||
WriteOpenBraceAndIndent();
|
||||
WriteLine($"if (!initialized)");
|
||||
{
|
||||
WriteOpenBraceAndIndent();
|
||||
|
@ -1799,18 +1752,16 @@ namespace CppSharp.Generators.CSharp
|
|||
}
|
||||
|
||||
WriteLine("return VTables;");
|
||||
UnindentAndWriteCloseBrace();
|
||||
}
|
||||
}
|
||||
UnindentAndWriteCloseBrace();
|
||||
NewLine();
|
||||
|
||||
if (!hasDynamicBase)
|
||||
WriteLine("protected CppSharp.Runtime.VTables __vtables;");
|
||||
|
||||
WriteLines($@"
|
||||
internal {(hasDynamicBase ? "override" : "virtual")} CppSharp.Runtime.VTables __VTables
|
||||
{{
|
||||
using (WriteBlock($"internal {(hasDynamicBase ? "override" : "virtual")} CppSharp.Runtime.VTables __VTables"))
|
||||
{
|
||||
WriteLines($@"
|
||||
get {{
|
||||
if (__vtables.IsEmpty)
|
||||
__vtables.Tables = {($"new IntPtr[] {{ {string.Join(", ", originalTableClass.Layout.VTablePointers.Select(x => $"*(IntPtr*)({Helpers.InstanceIdentifier} + {x.Offset})"))} }}")};
|
||||
|
@ -1819,14 +1770,15 @@ namespace CppSharp.Generators.CSharp
|
|||
|
||||
set {{
|
||||
__vtables = value;
|
||||
}}
|
||||
}}
|
||||
}}", trimIndentation: true);
|
||||
}
|
||||
|
||||
internal {(hasDynamicBase ? "override" : "virtual")} void SetupVTables(bool destructorOnly = false)
|
||||
{{
|
||||
using (WriteBlock($"internal {(hasDynamicBase ? "override" : "virtual")} void SetupVTables(bool destructorOnly = false)"))
|
||||
{
|
||||
WriteLines($@"
|
||||
if (__VTables.IsTransient)
|
||||
__VTables = VTableLoader.SetupVTables(__Instance, destructorOnly);
|
||||
}}", trimIndentation: true);
|
||||
__VTables = VTableLoader.SetupVTables(__Instance, destructorOnly);", trimIndentation: true);
|
||||
}
|
||||
|
||||
WriteLine("#endregion");
|
||||
PopBlock(NewLineKind.BeforeNextBlock);
|
||||
|
@ -1910,8 +1862,7 @@ namespace CppSharp.Generators.CSharp
|
|||
return;
|
||||
}
|
||||
var typeFullName = TypePrinter.VisitClassDecl(@class);
|
||||
WriteLine($@"SetupVTables(GetType().FullName == ""{
|
||||
typeFullName.Type.Replace("global::", string.Empty)}"");");
|
||||
WriteLine($@"SetupVTables(GetType().FullName == ""{typeFullName.Type.Replace("global::", string.Empty)}"");");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2012,8 +1963,7 @@ namespace CppSharp.Generators.CSharp
|
|||
if (method.HasIndirectReturnTypeParameter)
|
||||
{
|
||||
var retParam = method.Parameters.First(p => p.Kind == ParameterKind.IndirectReturnType);
|
||||
WriteLine($@"*({TypePrinter.PrintNative(method.OriginalReturnType)}*) {
|
||||
retParam.Name} = {marshal.Context.ArgumentPrefix}{marshal.Context.Return};");
|
||||
WriteLine($@"*({TypePrinter.PrintNative(method.OriginalReturnType)}*) {retParam.Name} = {marshal.Context.ArgumentPrefix}{marshal.Context.Return};");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2051,20 +2001,14 @@ namespace CppSharp.Generators.CSharp
|
|||
var vTableMethodDelegateName = GetVTableMethodDelegateName(method);
|
||||
TypePrinter.PopMarshalKind();
|
||||
|
||||
WriteLine("private static {0} {1}Instance;",
|
||||
method.FunctionType.ToString(),
|
||||
vTableMethodDelegateName);
|
||||
WriteLine($"private static {method.FunctionType} {vTableMethodDelegateName}Instance;");
|
||||
NewLine();
|
||||
|
||||
WriteLine("private static {0} {1}Hook({2})", retType, vTableMethodDelegateName,
|
||||
string.Join(", ", @params));
|
||||
WriteOpenBraceAndIndent();
|
||||
|
||||
var printedClass = @class.Visit(TypePrinter);
|
||||
WriteLine($@"var {Helpers.TargetIdentifier} = {printedClass}.__GetInstance({Helpers.InstanceField});");
|
||||
GenerateVTableManagedCall(method);
|
||||
|
||||
UnindentAndWriteCloseBrace();
|
||||
using (WriteBlock($"private static {retType} {vTableMethodDelegateName}Hook({string.Join(", ", @params)})"))
|
||||
{
|
||||
WriteLine($@"var {Helpers.TargetIdentifier} = {@class.Visit(TypePrinter)}.__GetInstance({Helpers.InstanceField});");
|
||||
GenerateVTableManagedCall(method);
|
||||
}
|
||||
|
||||
PopBlock(NewLineKind.Always);
|
||||
}
|
||||
|
@ -2241,7 +2185,7 @@ namespace CppSharp.Generators.CSharp
|
|||
return;
|
||||
|
||||
using (PushWriteBlock(BlockKind.Finalizer, $"~{@class.Name}()", NewLineKind.BeforeNextBlock))
|
||||
WriteLine($"Dispose(false, callNativeDtor : { Helpers.OwnsNativeInstanceIdentifier} );");
|
||||
WriteLine($"Dispose(false, callNativeDtor : {Helpers.OwnsNativeInstanceIdentifier} );");
|
||||
}
|
||||
|
||||
private void GenerateDisposeMethods(Class @class)
|
||||
|
@ -2253,7 +2197,7 @@ namespace CppSharp.Generators.CSharp
|
|||
{
|
||||
using (PushWriteBlock(BlockKind.Method, "public void Dispose()", NewLineKind.BeforeNextBlock))
|
||||
{
|
||||
WriteLine($"Dispose(disposing: true, callNativeDtor : { Helpers.OwnsNativeInstanceIdentifier} );");
|
||||
WriteLine($"Dispose(disposing: true, callNativeDtor : {Helpers.OwnsNativeInstanceIdentifier} );");
|
||||
if (Options.GenerateFinalizerFor(@class))
|
||||
WriteLine("GC.SuppressFinalize(this);");
|
||||
}
|
||||
|
@ -2436,12 +2380,12 @@ internal static{(@new ? " new" : string.Empty)} {printedClass} __GetInstance({Ty
|
|||
|
||||
if (generateNativeToManaged)
|
||||
{
|
||||
WriteLines($@"
|
||||
WriteLines($@"
|
||||
if (!{Helpers.TryGetNativeToManagedMappingIdentifier}(native, out var managed))
|
||||
throw new global::System.Exception(""No managed instance was found"");");
|
||||
}
|
||||
}
|
||||
|
||||
WriteLines($@"
|
||||
WriteLines($@"
|
||||
var result = ({printedClass})managed;
|
||||
if (result.{Helpers.OwnsNativeInstanceIdentifier})
|
||||
result.SetupVTables();
|
||||
|
@ -2520,31 +2464,7 @@ WriteLines($@"
|
|||
if (@class.IsRefType && !@class.IsAbstract)
|
||||
{
|
||||
PushBlock(BlockKind.Method);
|
||||
WriteLine($"private static void* __CopyValue({@internal} native)");
|
||||
WriteOpenBraceAndIndent();
|
||||
var copyCtorMethod = @class.Methods.FirstOrDefault(method =>
|
||||
method.IsCopyConstructor);
|
||||
if (@class.HasNonTrivialCopyConstructor && copyCtorMethod != null &&
|
||||
copyCtorMethod.IsGenerated)
|
||||
{
|
||||
// Allocate memory for a new native object and call the ctor.
|
||||
WriteLine($"var ret = Marshal.AllocHGlobal(sizeof({@internal}));");
|
||||
var printed = TypePrinter.PrintNative(@class);
|
||||
string defaultValue = string.Empty;
|
||||
if (copyCtorMethod.Parameters.Count > 1)
|
||||
defaultValue = $", {ExpressionPrinter.VisitParameter(copyCtorMethod.Parameters.Last())}";
|
||||
WriteLine($@"{printed}.{GetFunctionNativeIdentifier(copyCtorMethod)}(ret, new {
|
||||
TypePrinter.IntPtrType}(&native){defaultValue});",
|
||||
printed, GetFunctionNativeIdentifier(copyCtorMethod));
|
||||
WriteLine("return ret.ToPointer();");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine($"var ret = Marshal.AllocHGlobal(sizeof({@internal}));");
|
||||
WriteLine($"*({@internal}*) ret = native;");
|
||||
WriteLine("return ret.ToPointer();");
|
||||
}
|
||||
UnindentAndWriteCloseBrace();
|
||||
Generate__CopyValue(@class, @internal);
|
||||
PopBlock(NewLineKind.BeforeNextBlock);
|
||||
}
|
||||
if (!@class.IsAbstract)
|
||||
|
@ -2569,23 +2489,31 @@ WriteLines($@"
|
|||
}
|
||||
}
|
||||
|
||||
private void GenerateClassConstructorBase(Class @class, Method method)
|
||||
private void Generate__CopyValue(Class @class, string @internal)
|
||||
{
|
||||
var hasBase = @class.HasBaseClass;
|
||||
|
||||
if (hasBase && !@class.IsValueType)
|
||||
using (WriteBlock($"private static void* __CopyValue({@internal} native)"))
|
||||
{
|
||||
Indent();
|
||||
Write(": this(");
|
||||
var copyCtorMethod = @class.Methods.FirstOrDefault(method => method.IsCopyConstructor);
|
||||
|
||||
Write(method != null ? "(void*) null" : "native");
|
||||
|
||||
WriteLine(")");
|
||||
Unindent();
|
||||
if (@class.HasNonTrivialCopyConstructor && copyCtorMethod != null && copyCtorMethod.IsGenerated)
|
||||
{
|
||||
// Allocate memory for a new native object and call the ctor.
|
||||
var printed = TypePrinter.PrintNative(@class);
|
||||
string defaultValue = string.Empty;
|
||||
if (copyCtorMethod.Parameters.Count > 1)
|
||||
defaultValue = $", {ExpressionPrinter.VisitParameter(copyCtorMethod.Parameters.Last())}";
|
||||
WriteLine($@"var ret = Marshal.AllocHGlobal(sizeof({@internal}));");
|
||||
WriteLine($@"{printed}.{GetFunctionNativeIdentifier(copyCtorMethod)}(ret, new {TypePrinter.IntPtrType}(&native){defaultValue});",
|
||||
printed, GetFunctionNativeIdentifier(copyCtorMethod));
|
||||
WriteLine("return ret.ToPointer();");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine($"var ret = Marshal.AllocHGlobal(sizeof({@internal}));");
|
||||
WriteLine($"*({@internal}*) ret = native;");
|
||||
WriteLine("return ret.ToPointer();");
|
||||
}
|
||||
}
|
||||
|
||||
if (@class.IsValueType)
|
||||
WriteLineIndent(": this()");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -2600,17 +2528,15 @@ WriteLines($@"
|
|||
var functionName = GetFunctionIdentifier(function);
|
||||
if (functionName == parentName)
|
||||
functionName += '_';
|
||||
Write("public static {0} {1}(", function.OriginalReturnType, functionName);
|
||||
Write(FormatMethodParameters(function.Parameters));
|
||||
WriteLine(")");
|
||||
WriteOpenBraceAndIndent();
|
||||
|
||||
if (function.SynthKind == FunctionSynthKind.DefaultValueOverload)
|
||||
GenerateOverloadCall(function);
|
||||
else
|
||||
GenerateInternalFunctionCall(function);
|
||||
using (WriteBlock($"public static {function.OriginalReturnType} {functionName}({FormatMethodParameters(function.Parameters)})"))
|
||||
{
|
||||
if (function.SynthKind == FunctionSynthKind.DefaultValueOverload)
|
||||
GenerateOverloadCall(function);
|
||||
else
|
||||
GenerateInternalFunctionCall(function);
|
||||
}
|
||||
|
||||
UnindentAndWriteCloseBrace();
|
||||
PopBlock(NewLineKind.BeforeNextBlock);
|
||||
}
|
||||
|
||||
|
@ -2636,25 +2562,17 @@ WriteLines($@"
|
|||
Write("abstract ");
|
||||
|
||||
var functionName = GetMethodIdentifier(method);
|
||||
|
||||
var printedType = method.OriginalReturnType.Visit(TypePrinter);
|
||||
var parameters = FormatMethodParameters(method.Parameters);
|
||||
|
||||
if (method.IsConstructor || method.IsDestructor)
|
||||
Write("{0}(", functionName);
|
||||
Write($"{functionName}({parameters})");
|
||||
else if (method.ExplicitInterfaceImpl != null)
|
||||
Write("{0} {1}.{2}(", printedType,
|
||||
method.ExplicitInterfaceImpl.Name, functionName);
|
||||
else if (method.OperatorKind == CXXOperatorKind.Conversion ||
|
||||
method.OperatorKind == CXXOperatorKind.ExplicitConversion)
|
||||
{
|
||||
Write($"{functionName} {printedType}(");
|
||||
}
|
||||
Write($"{printedType} {method.ExplicitInterfaceImpl.Name}.{functionName}({parameters})");
|
||||
else if (method.OperatorKind == CXXOperatorKind.Conversion || method.OperatorKind == CXXOperatorKind.ExplicitConversion)
|
||||
Write($"{functionName} {printedType}({parameters})");
|
||||
else
|
||||
Write("{0} {1}(", printedType, functionName);
|
||||
|
||||
Write(FormatMethodParameters(method.Parameters));
|
||||
|
||||
Write(")");
|
||||
Write($"{printedType} {functionName}({parameters})", printedType);
|
||||
}
|
||||
|
||||
public void GenerateMethod(Method method, Class @class)
|
||||
|
@ -2688,7 +2606,15 @@ WriteLines($@"
|
|||
|
||||
if (method.Kind == CXXMethodKind.Constructor &&
|
||||
method.SynthKind != FunctionSynthKind.DefaultValueOverload)
|
||||
GenerateClassConstructorBase(@class, method);
|
||||
{
|
||||
var hasBase = @class.HasBaseClass;
|
||||
|
||||
if (hasBase && !@class.IsValueType)
|
||||
WriteLineIndent($": this({(method != null ? "(void*) null" : "native")})");
|
||||
|
||||
if (@class.IsValueType)
|
||||
WriteLineIndent(": this()");
|
||||
}
|
||||
|
||||
WriteOpenBraceAndIndent();
|
||||
|
||||
|
@ -2721,7 +2647,13 @@ WriteLines($@"
|
|||
|
||||
if (method.OperatorKind == CXXOperatorKind.EqualEqual)
|
||||
{
|
||||
GenerateEqualsAndGetHashCode(method, @class);
|
||||
if (ShouldGenerateEqualsAndGetHashCode(@class, method))
|
||||
{
|
||||
NewLine();
|
||||
GenerateEquals(@class);
|
||||
NewLine();
|
||||
GenerateGetHashCode(@class);
|
||||
}
|
||||
}
|
||||
|
||||
PopBlock(NewLineKind.BeforeNextBlock);
|
||||
|
@ -2737,18 +2669,12 @@ WriteLines($@"
|
|||
m => m.InstantiatedFrom == (method.OriginalFunction ?? method));
|
||||
if (specializedMethod == null)
|
||||
{
|
||||
WriteLine($@"throw new MissingMethodException(""Method {
|
||||
method.Name} missing from explicit specialization {
|
||||
@class.Visit(TypePrinter)}."");");
|
||||
|
||||
WriteLine($@"throw new MissingMethodException(""Method {method.Name} missing from explicit specialization {@class.Visit(TypePrinter)}."");");
|
||||
return false;
|
||||
}
|
||||
if (specializedMethod.Ignore)
|
||||
{
|
||||
WriteLine($@"throw new MissingMethodException(""Method {
|
||||
method.Name} ignored in specialization {
|
||||
@class.Visit(TypePrinter)}."");");
|
||||
|
||||
WriteLine($@"throw new MissingMethodException(""Method {method.Name} ignored in specialization {@class.Visit(TypePrinter)}."");");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2828,8 +2754,7 @@ WriteLines($@"
|
|||
parameter.Usage == ParameterUsage.InOut && parameter.HasDefaultValue)
|
||||
{
|
||||
var pointeeType = ((PointerType)parameter.Type).Pointee.ToString();
|
||||
WriteLine($@"{pointeeType} param{j++} = {
|
||||
(primitiveType == PrimitiveType.Bool ? "false" : "0")};");
|
||||
WriteLine($@"{pointeeType} param{j++} = {(primitiveType == PrimitiveType.Bool ? "false" : "0")};");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2851,49 +2776,46 @@ WriteLines($@"
|
|||
(p.Usage == ParameterUsage.InOut ? "ref " : string.Empty) + p.Name)));
|
||||
}
|
||||
|
||||
private void GenerateEqualsAndGetHashCode(Function method, Class @class)
|
||||
private bool ShouldGenerateEqualsAndGetHashCode(Class @class, Function method)
|
||||
{
|
||||
Class leftHandSide;
|
||||
Class rightHandSide;
|
||||
if (method.Parameters[0].Type.SkipPointerRefs().TryGetClass(out leftHandSide) &&
|
||||
leftHandSide.OriginalPtr == @class.OriginalPtr &&
|
||||
method.Parameters[1].Type.SkipPointerRefs().TryGetClass(out rightHandSide) &&
|
||||
rightHandSide.OriginalPtr == @class.OriginalPtr)
|
||||
return method.Parameters[0].Type.SkipPointerRefs().TryGetClass(out Class leftHandSide)
|
||||
&& leftHandSide.OriginalPtr == @class.OriginalPtr
|
||||
&& method.Parameters[1].Type.SkipPointerRefs().TryGetClass(out Class rightHandSide)
|
||||
&& rightHandSide.OriginalPtr == @class.OriginalPtr;
|
||||
}
|
||||
|
||||
private void GenerateEquals(Class @class)
|
||||
{
|
||||
using (WriteBlock("public override bool Equals(object obj)"))
|
||||
{
|
||||
NewLine();
|
||||
WriteLine("public override bool Equals(object obj)");
|
||||
WriteOpenBraceAndIndent();
|
||||
var printedClass = @class.Visit(TypePrinter);
|
||||
if (@class.IsRefType)
|
||||
{
|
||||
WriteLine($"return this == obj as {printedClass};");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine($"if (!(obj is {printedClass})) return false;");
|
||||
WriteLine($"return this == ({printedClass}) obj;");
|
||||
}
|
||||
UnindentAndWriteCloseBrace();
|
||||
|
||||
NewLine();
|
||||
|
||||
WriteLine("public override int GetHashCode()");
|
||||
WriteOpenBraceAndIndent();
|
||||
if (@class.IsRefType)
|
||||
this.GenerateMember(@class, GenerateGetHashCode);
|
||||
else
|
||||
WriteLine($"return {Helpers.InstanceIdentifier}.GetHashCode();");
|
||||
UnindentAndWriteCloseBrace();
|
||||
}
|
||||
}
|
||||
|
||||
private bool GenerateGetHashCode(Class @class)
|
||||
private void GenerateGetHashCode(Class @class)
|
||||
{
|
||||
WriteLine($"if ({Helpers.InstanceIdentifier} == {TypePrinter.IntPtrType}.Zero)");
|
||||
WriteLineIndent($"return {TypePrinter.IntPtrType}.Zero.GetHashCode();");
|
||||
WriteLine($@"return (*({TypePrinter.PrintNative(@class)}*) {
|
||||
Helpers.InstanceIdentifier}).GetHashCode();");
|
||||
return false;
|
||||
using (WriteBlock("public override int GetHashCode()"))
|
||||
{
|
||||
if (!@class.IsRefType)
|
||||
WriteLine($"return {Helpers.InstanceIdentifier}.GetHashCode();");
|
||||
else
|
||||
{
|
||||
this.GenerateMember(@class, c =>
|
||||
{
|
||||
WriteLine($"if ({Helpers.InstanceIdentifier} == {TypePrinter.IntPtrType}.Zero)");
|
||||
WriteLineIndent($"return {TypePrinter.IntPtrType}.Zero.GetHashCode();");
|
||||
WriteLine($@"return (*({TypePrinter.PrintNative(c)}*) {Helpers.InstanceIdentifier}).GetHashCode();");
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateVirtualFunctionCall(Method method,
|
||||
|
@ -3014,8 +2936,7 @@ WriteLines($@"
|
|||
else
|
||||
{
|
||||
var classInternal = TypePrinter.PrintNative(@class);
|
||||
WriteLine($@"*(({classInternal}*) {Helpers.InstanceIdentifier}) = *(({
|
||||
classInternal}*) {method.Parameters[0].Name}.{Helpers.InstanceIdentifier});");
|
||||
WriteLine($@"*(({classInternal}*) {Helpers.InstanceIdentifier}) = *(({classInternal}*) {method.Parameters[0].Name}.{Helpers.InstanceIdentifier});");
|
||||
|
||||
// Copy any string references owned by the source to the new instance so we
|
||||
// don't have to ref count them.
|
||||
|
@ -3108,8 +3029,7 @@ WriteLines($@"
|
|||
Class retClass;
|
||||
type.TryGetClass(out retClass);
|
||||
var @class = retClass.OriginalClass ?? retClass;
|
||||
WriteLine($@"var {Helpers.ReturnIdentifier} = new {
|
||||
TypePrinter.PrintNative(@class)}();");
|
||||
WriteLine($@"var {Helpers.ReturnIdentifier} = new {TypePrinter.PrintNative(@class)}();");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3170,9 +3090,7 @@ WriteLines($@"
|
|||
{
|
||||
if (operatorParam == null)
|
||||
{
|
||||
WriteLine($@"fixed ({Helpers.InternalStruct}{
|
||||
Helpers.GetSuffixForInternal((Class)originalFunction.Namespace)}* __instancePtr = &{
|
||||
Helpers.InstanceField})");
|
||||
WriteLine($@"fixed ({Helpers.InternalStruct}{Helpers.GetSuffixForInternal((Class)originalFunction.Namespace)}* __instancePtr = &{Helpers.InstanceField})");
|
||||
WriteOpenBraceAndIndent();
|
||||
}
|
||||
else
|
||||
|
@ -3187,13 +3105,12 @@ WriteLines($@"
|
|||
if (method != null && !method.IsConstructor && method.OriginalFunction != null &&
|
||||
((Method)method.OriginalFunction).IsConstructor)
|
||||
{
|
||||
WriteLine($@"Marshal.AllocHGlobal({
|
||||
((Class)method.OriginalNamespace).Layout.Size});");
|
||||
WriteLine($@"Marshal.AllocHGlobal({((Class)method.OriginalNamespace).Layout.Size});");
|
||||
names.Insert(0, Helpers.ReturnIdentifier);
|
||||
}
|
||||
WriteLine("{0}({1});", functionName, string.Join(", ", names));
|
||||
|
||||
foreach(var param in @params)
|
||||
foreach (var param in @params)
|
||||
{
|
||||
if (param.Param.IsInOut && param.Param.Type.IsReferenceToPtrToClass())
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче