Browse Source

Copy arrays of primitive values using System.Buffers.MemoryCopy (#1440)

pull/1445/head
josetr 5 years ago committed by GitHub
parent
commit
133a1882df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/AST/TypeExtensions.cs
  2. 18
      src/Generator/Generators/CSharp/CSharpMarshal.cs

5
src/AST/TypeExtensions.cs

@ -435,5 +435,10 @@
return declaration.TranslationUnit.Module; return declaration.TranslationUnit.Module;
} }
public static long GetSizeInBytes(this ArrayType array)
{
return array.Size * (array.ElementSize / 8);
}
} }
} }

18
src/Generator/Generators/CSharp/CSharpMarshal.cs

@ -80,12 +80,23 @@ namespace CppSharp.Generators.CSharp
supportBefore.WriteLine($"if ({Context.ReturnVarName} != null)"); supportBefore.WriteLine($"if ({Context.ReturnVarName} != null)");
supportBefore.WriteOpenBraceAndIndent(); supportBefore.WriteOpenBraceAndIndent();
supportBefore.WriteLine($"{value} = new {arrayType}[{array.Size}];"); supportBefore.WriteLine($"{value} = new {arrayType}[{array.Size}];");
if (CheckIfArrayCanBeCopiedUsingMemoryCopy(array))
{
var arraySizeInBytes = array.GetSizeInBytes();
var fixedArray = Generator.GeneratedIdentifier($"{value}fixed");
supportBefore.WriteLine($"fixed (void* {fixedArray} = {value})");
supportBefore.WriteLineIndent(
$"System.Buffer.MemoryCopy((void*){Context.ReturnVarName}, {fixedArray}, {arraySizeInBytes}, {arraySizeInBytes});");
}
else {
supportBefore.WriteLine($"for (int i = 0; i < {array.Size}; i++)"); supportBefore.WriteLine($"for (int i = 0; i < {array.Size}; i++)");
if (array.Type.IsPointerToPrimitiveType(PrimitiveType.Void)) if (array.Type.IsPointerToPrimitiveType(PrimitiveType.Void))
supportBefore.WriteLineIndent($@"{value}[i] = new global::System.IntPtr({ supportBefore.WriteLineIndent($@"{value}[i] = new global::System.IntPtr({
Context.ReturnVarName}[i]);"); Context.ReturnVarName}[i]);");
else else
{ {
var finalArrayType = arrayType.GetPointee() ?? arrayType; var finalArrayType = arrayType.GetPointee() ?? arrayType;
Class @class; Class @class;
if ((finalArrayType.TryGetClass(out @class)) && @class.IsRefType) if ((finalArrayType.TryGetClass(out @class)) && @class.IsRefType)
@ -114,6 +125,7 @@ namespace CppSharp.Generators.CSharp
Context.ReturnVarName}[i];"); Context.ReturnVarName}[i];");
} }
} }
}
supportBefore.UnindentAndWriteCloseBrace(); supportBefore.UnindentAndWriteCloseBrace();
Context.Return.Write(value); Context.Return.Write(value);
break; break;
@ -428,6 +440,12 @@ namespace CppSharp.Generators.CSharp
Context.Return.Write(intermediateArray); Context.Return.Write(intermediateArray);
} }
public bool CheckIfArrayCanBeCopiedUsingMemoryCopy(ArrayType array)
{
return array.Type.IsPrimitiveType(out var primitive) &&
(!Context.Context.Options.MarshalCharAsManagedChar || primitive != PrimitiveType.Char);
}
private readonly CSharpTypePrinter typePrinter; private readonly CSharpTypePrinter typePrinter;
} }

Loading…
Cancel
Save