-
Notifications
You must be signed in to change notification settings - Fork 517
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Rgen] Add the needed code to make the objc_msgSend signatures. (#22029)
Add the code that will calculate the signature needed in the objc_msgSend which will be the method that calls the native objc message. ## Extra context When we create a binding for a native type we need to be able to send 'messages' to the objc objects. From a C# developer perspective a message can be considered a method. So for example, the following objc code: ```objc [object foo:bar]; ``` Can be translated to: ```c objc_msgSend(object, sel_getUid("foo:"), bar); ``` We can say this process is similar to reflection and the[ Invoke method](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.invoke?view=net-9.0). Our bindings provide methods around [objc_msgsend](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend) which we use to send the messaged with the arguments needed by the message. For example, a property with a NSString backing fields defined as: ```csharp [Export ("text")] public string? Text { get; set; } ``` Results in the following generated code: ```csharp [BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)] public virtual string? Text { [Export ("text")] get { global::UIKit.UIApplication.EnsureUIThread (); if (IsDirectBinding) { return CFString.FromHandle (global::ObjCRuntime.Messaging.NativeHandle_objc_msgSend (this.Handle, Selector.GetHandle ("text")), false)!; } else { return CFString.FromHandle (global::ObjCRuntime.Messaging.NativeHandle_objc_msgSendSuper (this.SuperHandle, Selector.GetHandle ("text")), false)!; } } [Export ("setText:")] set { global::UIKit.UIApplication.EnsureUIThread (); var nsvalue = CFString.CreateNative (value); if (IsDirectBinding) { global::ObjCRuntime.Messaging.void_objc_msgSend_NativeHandle (this.Handle, Selector.GetHandle ("setText:"), nsvalue); } else { global::ObjCRuntime.Messaging.void_objc_msgSendSuper_NativeHandle (this.SuperHandle, Selector.GetHandle ("setText:"), nsvalue); } CFString.ReleaseNative (nsvalue); } } ``` Our objc_msgSend method signatures are calculated based on the method parameters and live in the runtime. These objc_msgSend calls are generated by https://github.com/xamarin/xamarin-macios/blob/main/runtime/bindings-generator.cs#L20 For example a objc_msgSend signature for a method that takes a string and returns a string would be: ```c IntPtr_objc_msgSend_IntPtr ``` But this is a simplifications because there is a diff between sending a message to a super class (prefix super) or if it deals with a structure (stret). More info can be found in the Apple [documentation](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend). --------- Co-authored-by: GitHub Actions Autoformatter <[email protected]> Co-authored-by: Copilot <[email protected]>
- Loading branch information
1 parent
e62a38f
commit d52838b
Showing
18 changed files
with
937 additions
and
41 deletions.
There are no files selected for viewing
37 changes: 37 additions & 0 deletions
37
src/rgen/Microsoft.Macios.Generator/Attributes/MarshalDirective.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
|
||
namespace Microsoft.Macios.Generator.Attributes; | ||
|
||
record CustomMarshalDirective (string? NativePrefix, string? NativeSuffix, string? Library); | ||
|
||
static class ExportDataExtensions { | ||
|
||
public static bool ShouldMarshalNativeExceptions<T> (this ExportData<T> self) where T : Enum | ||
=> self switch { | ||
ExportData<ObjCBindings.Property> property => property.Flags.HasFlag (ObjCBindings.Property | ||
.CustomMarshalDirective), | ||
ExportData<ObjCBindings.Method> method => method.Flags.HasFlag ( | ||
ObjCBindings.Property.CustomMarshalDirective), | ||
_ => false, | ||
}; | ||
|
||
public static CustomMarshalDirective? ToCustomMarshalDirective<T> (this ExportData<T> self) where T : Enum | ||
{ | ||
var present = self switch { | ||
ExportData<ObjCBindings.Property> property => property.Flags.HasFlag (ObjCBindings.Property | ||
.CustomMarshalDirective), | ||
ExportData<ObjCBindings.Method> method => method.Flags.HasFlag ( | ||
ObjCBindings.Property.CustomMarshalDirective), | ||
_ => false, | ||
}; | ||
if (present) { | ||
return new (self.NativePrefix, self.NativeSuffix, self.Library); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.