Browse Source

Generate valid C# for template indexers taking const char*

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1204/head
Dimitar Dobrev 6 years ago
parent
commit
9bc39c44ab
  1. 6
      src/AST/Type.cs
  2. 10
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  3. 8
      src/Generator/Generators/CSharp/CSharpSources.cs
  4. 2
      src/Generator/Generators/CSharp/CSharpSourcesExtensions.cs
  5. 27
      src/Generator/Types/Std/Stdlib.cs
  6. 4
      tests/CSharp/CSharpTemplates.h

6
src/AST/Type.cs

@ -866,10 +866,12 @@ namespace CppSharp.AST @@ -866,10 +866,12 @@ namespace CppSharp.AST
var type = obj as TemplateParameterSubstitutionType;
if (type == null) return false;
return Replacement.Equals(type.Replacement);
return ReplacedParameter.Equals(type.ReplacedParameter) &&
Replacement.Equals(type.Replacement);
}
public override int GetHashCode() => Replacement.GetHashCode();
public override int GetHashCode() =>
ReplacedParameter.GetHashCode() ^ Replacement.GetHashCode();
}
/// <summary>

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

@ -312,7 +312,8 @@ namespace CppSharp.Generators.CSharp @@ -312,7 +312,8 @@ namespace CppSharp.Generators.CSharp
Type finalType = (returnType.GetFinalPointee() ?? returnType).Desugar();
if (finalType.IsDependent)
Context.Return.Write($"({param.ReplacedParameter.Parameter.Name}) (object) ");
if (param.Replacement.Type.Desugar().IsPointerToPrimitiveType())
Type replacement = param.Replacement.Type.Desugar();
if (replacement.IsPointerToPrimitiveType() && !replacement.IsConstCharString())
Context.Return.Write($"({typePrinter.IntPtrType}) ");
return base.VisitTemplateParameterSubstitutionType(param, quals);
}
@ -623,9 +624,10 @@ namespace CppSharp.Generators.CSharp @@ -623,9 +624,10 @@ namespace CppSharp.Generators.CSharp
public override bool VisitTemplateParameterSubstitutionType(TemplateParameterSubstitutionType param, TypeQualifiers quals)
{
var replacement = param.Replacement.Type.Desugar();
if (replacement.IsPrimitiveType() ||
replacement.IsPointerToPrimitiveType() ||
replacement.IsEnum())
if ((replacement.IsPrimitiveType() ||
replacement.IsPointerToPrimitiveType() ||
replacement.IsEnum()) &&
!replacement.IsConstCharString())
{
Context.Return.Write($"({replacement}) ");
if (replacement.IsPointerToPrimitiveType())

8
src/Generator/Generators/CSharp/CSharpSources.cs

@ -1049,15 +1049,15 @@ namespace CppSharp.Generators.CSharp @@ -1049,15 +1049,15 @@ namespace CppSharp.Generators.CSharp
if (type.IsPrimitiveType())
{
WriteLine($@"*{@internal}.{internalFunction}({
GetInstanceParam(function)}, {(paramMarshal.Context == null ?
paramMarshal.Name : paramMarshal.Context.Return)}) = {marshal.Context.Return};");
GetInstanceParam(function)}, {paramMarshal.Context.ArgumentPrefix}{
paramMarshal.Name}) = {marshal.Context.Return};");
}
else
{
var typeInternal = TypePrinter.PrintNative(type);
WriteLine($@"*({typeInternal}*) {@internal}.{internalFunction}({
GetInstanceParam(function)}, {(paramMarshal.Context == null ?
paramMarshal.Name : paramMarshal.Context.Return)}) = {marshal.Context.Return};");
GetInstanceParam(function)}, {paramMarshal.Context.ArgumentPrefix}{
paramMarshal.Name}) = {marshal.Context.Return};");
}
}

2
src/Generator/Generators/CSharp/CSharpSourcesExtensions.cs

@ -139,7 +139,7 @@ namespace CppSharp.Generators.CSharp @@ -139,7 +139,7 @@ namespace CppSharp.Generators.CSharp
i =>
{
CppSharp.AST.Type type = specialization.Arguments[i].Type.Type;
return type.IsPointerToPrimitiveType() ?
return type.IsPointerToPrimitiveType() && !type.IsConstCharString() ?
$"__{@class.TemplateParameters[i].Name}.FullName == \"System.IntPtr\"" :
$"__{@class.TemplateParameters[i].Name}.IsAssignableFrom(typeof({type}))";
})));

27
src/Generator/Types/Std/Stdlib.cs

@ -167,24 +167,31 @@ namespace CppSharp.Types.Std @@ -167,24 +167,31 @@ namespace CppSharp.Types.Std
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{
string param = ctx.Parameter.Name;
if (ctx.Parameter.Usage == ParameterUsage.Unknown &&
!ctx.Parameter.Type.IsReference() &&
!(ctx.Parameter.Type is TemplateParameterSubstitutionType) &&
ctx.MarshalKind != MarshalKind.NativeField &&
ctx.MarshalKind != MarshalKind.VTableReturnValue &&
ctx.MarshalKind != MarshalKind.Variable)
{
ctx.Return.Write(ctx.Parameter.Name);
ctx.Return.Write(param);
return;
}
var substitution = Type as TemplateParameterSubstitutionType;
if (substitution != null)
param = $"({substitution.Replacement}) (object) {param}";
if (Equals(Context.Options.Encoding, Encoding.ASCII))
{
ctx.Return.Write($"Marshal.StringToHGlobalAnsi({ctx.Parameter.Name})");
ctx.Return.Write($"Marshal.StringToHGlobalAnsi({param})");
return;
}
if (Equals(Context.Options.Encoding, Encoding.Unicode) ||
Equals(Context.Options.Encoding, Encoding.BigEndianUnicode))
{
ctx.Return.Write($"Marshal.StringToHGlobalUni({ctx.Parameter.Name})");
ctx.Return.Write($"Marshal.StringToHGlobalUni({param})");
return;
}
throw new System.NotSupportedException(
@ -200,7 +207,7 @@ namespace CppSharp.Types.Std @@ -200,7 +207,7 @@ namespace CppSharp.Types.Std
return;
}
Type type = ctx.ReturnType.Type.Desugar();
Type type = Type.Desugar();
Type pointee = type.GetPointee().Desugar();
var isChar = type.IsPointerToPrimitiveType(PrimitiveType.Char) ||
(pointee.IsPointerToPrimitiveType(PrimitiveType.Char) &&
@ -211,27 +218,31 @@ namespace CppSharp.Types.Std @@ -211,27 +218,31 @@ namespace CppSharp.Types.Std
if (Equals(encoding, Encoding.ASCII))
encoding = Context.Options.Encoding;
string returnVarName = ctx.Function != null &&
ctx.Function.ReturnType.Type.Desugar().IsAddress() ?
$"(global::System.IntPtr) {ctx.ReturnVarName}" : ctx.ReturnVarName;
if (Equals(encoding, Encoding.ASCII))
{
ctx.Return.Write($"Marshal.PtrToStringAnsi({ctx.ReturnVarName})");
ctx.Return.Write($"Marshal.PtrToStringAnsi({returnVarName})");
return;
}
if (Equals(encoding, Encoding.UTF8))
{
ctx.Return.Write($"Marshal.PtrToStringUTF8({ctx.ReturnVarName})");
ctx.Return.Write($"Marshal.PtrToStringUTF8({returnVarName})");
return;
}
// If we reach this, we know the string is Unicode.
if (isChar || ctx.Context.TargetInfo.WCharWidth == 16)
{
ctx.Return.Write($"Marshal.PtrToStringUni({ctx.ReturnVarName})");
ctx.Return.Write($"Marshal.PtrToStringUni({returnVarName})");
return;
}
// If we reach this, we should have an UTF-32 wide string.
const string encodingName = "System.Text.Encoding.UTF32";
ctx.Return.Write($@"CppSharp.Runtime.Helpers.MarshalEncodedString({
ctx.ReturnVarName}, {encodingName})");
returnVarName}, {encodingName})");
}
}

4
tests/CSharp/CSharpTemplates.h

@ -715,7 +715,8 @@ void forceUseSpecializations(IndependentFields<int> _1, IndependentFields<bool> @@ -715,7 +715,8 @@ void forceUseSpecializations(IndependentFields<int> _1, IndependentFields<bool>
TemplateDerivedFromRegularDynamic<RegularDynamic> _14,
IndependentFields<OnlySpecialisedInTypeArg<double>> _15,
DependentPointerFields<float> _16, IndependentFields<const T1&> _17,
TemplateWithIndexer<T2*> _18, IndependentFields<int(*)(int)>, std::string s);
TemplateWithIndexer<T2*> _18, IndependentFields<int(*)(int)> _19,
TemplateWithIndexer<const char*> _20, std::string s);
void hasIgnoredParam(DependentValueFields<IndependentFields<Ignored>> ii);
@ -750,6 +751,7 @@ template class DLL_API TemplateWithIndexer<UsedInTemplatedIndexer>; @@ -750,6 +751,7 @@ template class DLL_API TemplateWithIndexer<UsedInTemplatedIndexer>;
template class DLL_API TemplateWithIndexer<T1>;
template class DLL_API TemplateWithIndexer<T2*>;
template class DLL_API TemplateWithIndexer<float>;
template class DLL_API TemplateWithIndexer<const char*>;
template class DLL_API TemplateDerivedFromRegularDynamic<RegularDynamic>;
template class DLL_API HasCtorWithMappedToEnum<TestFlag>;

Loading…
Cancel
Save