Xamarin.ios 绑定Objective-C libraries中容易出现的问题
来源:互联网 发布:阿里云邮箱个性签名 编辑:程序博客网 时间:2024/05/18 01:29
This blog post is about producing better bindings of Objective-C libraries forXamarin.iOS and Xamarin.Mac . Read the series introduction to get a better idea why this is important and how it can save you time and headaches.
What can go wrong ?
Binding a selector using a correct [Export("")]
attribute is only half the job. The .NET method signature must match the one defined in Objective-C. Xamarin.iOS does some magic, like converting string
and NSString
, but you still need to be careful. The most common mistakes are:
- signed/unsigned types : this is often minor and you might want to disable the check on some (or even all) of them. CLS compliance means .NET developers prefer signed over unsigned integers (except for
byte
). Apple APIs often use unsigned integers when a number cannot be negative. For example:
@property (nonatomic, readwrite) NSUInteger loops;
[Export ("loops")]int Loops { get; set; }// should be uint, easier (less casting) if an int
- wrong types : a common case is a missing
ref
when the Objective-C API requires a pointer to a value, not the value itself. For example:
-(void) sphericalRadius:(float*) r zenith:(float*) zenith azimuth:(float*) azimuth;
[Export ("sphericalRadius:zenith:azimuth:")]void GetSphere (float radius, float zenith, float azimuth);// wrong, references to float (ref float) should have been used
- wrong size : this often happens on structures, but it can also occurs when a type name is misleading (e.g.
long
is 32 bits in Objective-C, at least for 32bits archs like i386 and ARM, while it is 64 bits on .NET) or when common usage differs, as in this case:
-(id) initWithDuration:(ccTime)duration red:(GLshort)deltaRed green:(GLshort)deltaGreen blue:(GLshort)deltaBlue;
[Export ("initWithDuration:red:green:blue:")]IntPtr Constructor (float duration, byte red, byte green, byte blue);// wrong, we're almost wired for bytes when seeing RGB but it does not have to be!
What can we check for ?
Quite a lot. It’s possible to get an encoded signature for selectors. The earlierloops
selector, for example, would return the “ I8@0:4
” string value.
From it we can extract the return value ( I
an unsigned int
) and all the parameters, e.g. self ( @
) and the selector ( :
) are always present and there are no other parameters since it’s a getter. We also get the size of the parameters, which can be compared to the size of the managed types used—and they should alwaysmatch!
Using all of the above, we can test pretty closely if an Objective-C signature matches the defined .NET signature. Simple? Not quite.
Objective-C encoding for structures is quite detailed. However, their internal names won’t match the one being used in your bindings. You’ll need to help the fixture to map them by overriding its IsValidStruct
method.
Why is this important ?
Signature mistakes are dangerous. Some APIs might (appear to) work, others will crash immediately (bad) or the crash will occur later (worse) because they will mess up the stack and cause memory corruption. Debugging such issues can be very time consuming, so your time is well invested in using this fixture.
How to fix issues ?
Fixing the .NET signature to match it’s Objectice-C peer is the most common case. The failure will tell you which parameter (or the return value) looks wrong. You have to confirm/fix this using the library’s documentation and/or it’s header files.
One notable (and uncommon) exception is the use of a variable number of arguments (e.g. var_list
in Objective-C, params
in C#). They are not part of the encoded signature, so once confirmed you can skip them by overriding theSkip(Type,MethodInfo,string)
method.
As discussed earlier, you might also want to override Check(char,Type)
to skip the signed/unsigned differences for integer types.
What’s missing ?
The encoded signature is not perfect. All NSObject
parameters are encoded as ‘@
‘ so we cannot detect if an NSData
should have been used instead of NSDate
. Since all objects are pointers, they all will be the same size ( IntPtr.Size
) so this will also not be noticed by the size check. Typos/errors, even if less common, are still possible.
This blog post concludes the five-part series on building better bindings for Xamarin.iOS and Xamarin.Mac. Thanks for reading!
原文链接:
http://blog.xamarin.com/producing-better-bindings-4-signatures/?utm_source=tuicool
http://www.tuicool.com/articles/6VvE73
- Xamarin.ios 绑定Objective-C libraries中容易出现的问题
- Xamarin.iOS使用Objective-C静态类库.a(Linking Native Libraries)
- Xamarin.iOS使用Objective-C静态类库.a(Linking Native Libraries)
- Xamarin演练:绑定一个Objective-C类库
- c++中new容易出现的问题
- 开发中容易出现的问题
- iOS中容易出错的问题
- 【C#开发iOS】Objective-C与C# with Xamarin的开发代码对比
- C语言中容易忽略的问题
- 关于C语言的memset容易出现的问题
- C#-多线程数据同步容易出现的异常问题
- 在C编程中容易出现的错误
- Xamarin.IOS Binding Objective Sharpie
- android开发中eclipse容易出现的问题
- android开发中eclipse容易出现的问题
- 关于html中table容易出现的问题
- 总结前端面试过程中最容易出现的问题
- 总结前端面试过程中最容易出现的问题
- Dreamweaver 8 锚点链接 下载链接和空链接
- const的作用
- 提示Can't load package:dclite70.bpl解决方法
- Android之SlidingPanelLayout
- Struts2
- Xamarin.ios 绑定Objective-C libraries中容易出现的问题
- Unity3D-Cube如何匀速经过空间中最小角度最终朝向空间任一位置
- 羽毛球正确的握拍方法(图文)
- [Leetcode]Convert Sorted List to Binary Search Tree
- Android调用系统自带的文件管理器进行文件选择
- Executing Selenium TestNG tests using ANT
- position 属性和 z-index 属性对页面节点层级影响的例子
- servlet启动服务的两种方式
- 随机样本选择——快速求解机器学习中的优化问题