Forum Cross Platform with Xamarin

How to ensure type safety when writing bindings?

I have a question about how to map Objective-C types to C# types when writing bindings.

I want to write some bindings for the Accelerate framework that is for both OSX and iOS. Writing the binding is straight forward but I am not sure about the right approach to ensure the types of the parameters are the correct size. E.g. Use a UInt32 versus a UInt versus a UInt16 when the type in the Accelerate framework is an int. And what about the storage required for an enum? C# is an int which is 32 bits - but does Objective-C follow the rules of ANSI-C?

In ANSI-C the storage requirement of an int is "a minimum of 16 bits." I am not sure what the rules are for Objective-C and C# - and whether there are other types I need to care about when writing bindings for cross-platform development.

I think the reason I need to care about this is because when I call the library each parameter will have used up a number of bytes on the stack and if the sizes are wrong the parameters will be popped off the stack incorrectly in the library.

The way I am handling this at the moment is writing some Objective-C and displaying the sizeof() before I write the binding - is there a smarter way?

Can anyone please point me to some rules on type size conversion when writing bindings?




  • adamkempadamkemp USInsider, Developer Group Leader mod

    While C has no rules for the size of primitives like int (aside from "int is at least as big as short), Objective-C does tend to favor typedefs that do have specific sizes. For instance, an NSInteger is a 32-bit integer on 32-bit architectures and 64-bit on 64-bit architectures. To map to into a C# binding you would use nint, which is a struct like IntPtr designed to adapt to the architecture it's run on.

    The most straightforward way to decided what the sizes will be is to look at the definition of the typedef and see whether it's defined to always be the same size or if it is based on a primitive that changes size. Typically it will fall into one of those two camps: either it's fixed at a certain size, or it's the size of a pointer. Therefore you just need to pick either a specific C# primitive that matches the fixed size or use nint/nuint.

Sign In or Register to comment.