[Mono-osx] MonoMac parser.cs

Duane Wandless duane at wandless.net
Tue Apr 20 10:59:19 EDT 2010


>
> In the particular case of NSArray and NSMutableArray our runtime has been
> extended to natively convert NSArrays to C# arrays and back so the only code
> that we bound is the required interop code for NSArray.
>

That is an interesting strategy and is limiting (I think).  How I use
NSMutableArrays is to populate them in C# then send then to the native obj-c
UI NSArrayControllers, etc.  I then can manipulate the array in C# and the
UI updates as expected.  If the only bindings exposed are to convert from a
List to NSArray then this use would not be possible.

Many bits from Foundation make sense for Objective-C programmers as they are
> dealing with a low-level language and are redundant with C#.
>

I believe this statement is not true, given how I use NSArrays.  I need to
be able to manipulate the underlying object so the UI is automatically
updated.

We do not currently support a mapping to categories as they do not really
> have a counter part in C#.
>

I may be too simple... but I view a category as nothing but additional
methods on the class.  But I may be missing some nuance of a category.

At a minimum I believe the bindings must expose the addObject, insertObject,
remove etc selectors on the arrays.

Duane

On Tue, Apr 20, 2010 at 10:03 AM, Miguel de Icaza <miguel at novell.com> wrote:

> Hello Duane,
>
> I have taken parser.cs and extended it to handle categories.  To start I
>> tested parsing NSArray.h.  This produced NSArray.cs and NSMutableArray.cs.
>> I have "full" bindings for these obj-c classes.
>>
>
> We do not currently support a mapping to categories as they do not really
> have a counter part in C#.
>
> They are *similar* to interfaces, but they can be interfaces with optional
> components so there is no direct mapping to them.
>
> For the delegate pattern we settled on classes that have been labeled as
> "Models" (read more about that on our binding page).
>
> NSMutableArray:  http://monobin.com/__m335d328c
>> NSArray:  http://monobin.com/__m36c66b6e
>
>
> Nice.  For the particular case of Foundation, we have taken an approach to
> only bind what is actually *required* as opposed to binding everything.
> Many bits from Foundation make sense for Objective-C programmers as they are
> dealing with a low-level language and are redundant with C#.
>
> In the particular case of NSArray and NSMutableArray our runtime has been
> extended to natively convert NSArrays to C# arrays and back so the only code
> that we bound is the required interop code for NSArray.
>
> So we suggest to work instead on the AppKit bindings.
>
> However not all the bindings generated are valid.  For example I do not
>> know how to generate a binding for this selector (note I do not use this
>> selector, just an example):
>> - (void)sortUsingFunction:(NSInteger (*)(id, id, void *))compare
>> context:(void *)context;
>>
>
> Correct, the parser does the heavy lifting, but requires human intervention
> to fix the output.
>
>>
>> Then comes the question of constructors.  Take these two (the 2nd is not
>> really a constructor I know) from NSMutableArray for example:
>> + (id)arrayWithCapacity:(NSUInteger)numItems;
>> - (id)initWithCapacity:(NSUInteger)numItems;
>>
>> My parser exposes these as:
>>
>>         [Static]
>>         [Export ("arrayWithCapacity:")]
>>         IntPtr ArrayWithCapacity (uint numItems);
>>
>>         [Export ("initWithCapacity:")]
>>         IntPtr InitWithCapacity (uint numItems);
>>
>
> This is a great question.
>
> Factory methods should be declared as static methods, and we *typically*
> use the FromXXXX or CreateXXX naming pattern for them, so the above would
> look like this:
>
> [Static, Export ("arrayWithCapacity:")]
> NSArray CreateArray (int items);
>
> Notice that I took the liberty of changing the uint to int because that
> makes the method CLS compliant.
>
> In this case it is a debatable change as there could be arrays with more
> than 2 gig elements, but in many other places in the API this is not the
> case, uint has been used to get an extra bit that is not required.
>
> So how can we support the extra 2 gigs of elements while still allowing
> other languages the most common use case?  We keep the signature as it was
> originally produced, and introduce a new overload:
>
> [Static, Export ("arrayWithCapacity:")]
> NSArray CreateArray (uint items);
>
> And then on a helper class in Foundation/NSArray.cs we would do:
>
> partial class NSArray {
>      static NSArray CreateArray (int items){
>           if (items < 0) throw new ArgumentException ();
>           return CreateArray ((uint) items);
>      }
> }
>
> Now to the second question:
>
> First I do not think returning an IntPtr is correct.  It should return
>> NSMutableArray.  But IntPtr follows what was started with MT.  Returning an
>> IntPtr will require calling GetNSObject which seems cumbersome.  Unless I'm
>> missing something.
>>
>
> In the specific case of *constructors*  the binding generator recognizes
> the pattern:
>
> IntPtr Constructor (ARGS)
>
> As being the constructor for the class.   This is required because
> constructors generate different code than regular method bindings.
>
> So you will see in all of our APIs that we expose that pattern, but that
> this is never translated into an actual exposed IntPtr, it is always
> translated into the correct method name.
>
> Miguel.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-osx/attachments/20100420/fff5762e/attachment.html 


More information about the Mono-osx mailing list