[bgen] Add support for delegates with pointer types. (#21159)
This commit is contained in:
Родитель
ff707c145e
Коммит
3b6a5c20c6
|
@ -718,6 +718,14 @@ public partial class Generator : IMemberGatherer {
|
|||
}
|
||||
}
|
||||
|
||||
if (pi.ParameterType.IsPointer && pi.ParameterType.GetElementType ().IsValueType) {
|
||||
// Technically we should only allow blittable types here, but the C# compiler shows an error later on if any non-blittable types
|
||||
// are used, because this ends up in the signature of a UnmanagedCallersOnly method.
|
||||
pars.Add (new TrampolineParameterInfo (TypeManager.FormatType (null, pi.ParameterType), safe_name));
|
||||
invoke.Append (safe_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pi.ParameterType.IsSubclassOf (TypeCache.System_Delegate)) {
|
||||
if (!delegate_types.ContainsKey (pi.ParameterType.Name)) {
|
||||
delegate_types [pi.ParameterType.FullName] = pi.ParameterType.GetMethod ("Invoke");
|
||||
|
@ -4731,11 +4739,13 @@ public partial class Generator : IMemberGatherer {
|
|||
print ("[MonoNativeFunctionWrapper]\n");
|
||||
|
||||
var accessibility = mi.DeclaringType.IsInternal (this) ? "internal" : "public";
|
||||
print ("{3} delegate {0} {1} ({2});",
|
||||
var isUnsafe = mi.GetParameters ().Any ((v => v.ParameterType.IsPointer)) || mi.ReturnType.IsPointer;
|
||||
print ("{3}{4} delegate {0} {1} ({2});",
|
||||
TypeManager.RenderType (mi.ReturnType, mi.ReturnTypeCustomAttributes),
|
||||
shortName,
|
||||
RenderParameterDecl (mi.GetParameters ()),
|
||||
accessibility);
|
||||
accessibility,
|
||||
isUnsafe ? " unsafe" : string.Empty);
|
||||
}
|
||||
|
||||
if (group.Namespace is not null) {
|
||||
|
|
|
@ -1719,5 +1719,20 @@ namespace GeneratorTests {
|
|||
var delegateCallback = bgen.ApiAssembly.MainModule.GetType ("NS", "MyCallback").Methods.First ((v) => v.Name == "EndInvoke");
|
||||
Assert.That (delegateCallback.MethodReturnType.CustomAttributes.Any (v => v.AttributeType.Name == "NullableAttribute"), "Nullable return type");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase (Profile.iOS)]
|
||||
public void DelegatesWithPointerTypes (Profile profile)
|
||||
{
|
||||
Configuration.IgnoreIfIgnoredPlatform (profile.AsPlatform ());
|
||||
var bgen = BuildFile (profile, "tests/delegate-types.cs");
|
||||
bgen.AssertNoWarnings ();
|
||||
|
||||
var delegateCallback = bgen.ApiAssembly.MainModule.GetType ("NS", "MyCallback").Methods.First ((v) => v.Name == "EndInvoke");
|
||||
Assert.IsTrue (delegateCallback.MethodReturnType.ReturnType.IsPointer, "Pointer return type");
|
||||
foreach (var p in delegateCallback.Parameters.Where (v => v.Name != "result")) {
|
||||
Assert.IsTrue (p.ParameterType.IsPointer, $"Pointer parameter type: {p.Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
|
||||
using Foundation;
|
||||
using ObjCRuntime;
|
||||
|
||||
namespace NS {
|
||||
unsafe delegate byte* MyCallback (sbyte* a, short* b, ushort* c, int* d, uint* e, long* f, ulong* g, float* h, double* i);
|
||||
|
||||
[BaseType (typeof (NSObject))]
|
||||
interface Widget {
|
||||
[Export ("foo")]
|
||||
[NullAllowed]
|
||||
MyCallback Foo { get; set; }
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче