Creating bindings for native, Objective-C based libraries can be somewhat confusing when first starting out. To help smooth the learning curve for those looking to create bindings (and hopefully share them) I have put together some links and an overview of the steps that I use.
As MonoTouch development is picking up steam again after the Novell/Xamarin deal I’ve noticed more and more people looking for help and information about just how to consume native libraries. Most of this information and the utility that auto-generates the code was gleaned from the #monotouch IRC channel, looking at other MonoTouch bindings and experimentation.
The core of this post was written in May 2011 when I was helping out a few folks with some binding issues. The general gist of the process still applies but somethings may have changed. Please let me know via comments or email if I am missing anything or if there are some corrections needed.
Step 1: Create the Binding Code
The binding that you are going to call from your C#/MonoTouch code you will need to create a C# version You can manually write the bindings by hand or use a utility to help automate the process. There is a tool you can compile from the source found in this gist that can help save some time. You will need to compile the tool using mcs and invoke it to generate the bindings like so :
The tool isn’t perfect and there are known issues. Cleaning this tool up is on my todo list but extremely low since I know the quirks and it is just faster for me to generate and fix it up than to polish it.
These are the biggest issues that those using the tool should be aware of:
- Methods are included correctly in their corresponding C# classes but properties aren’t. You’ll need to grab the properties and stick them in the right classes.
- If a method specified in a .h file spans multiple lines the tool can’t recognize that. When you go to compile you’ll get some errors.
- Delegates can be tricky. When creating delegate mappings need to update and figure out how to handle the delegates. Due to the brute force nature of the generator tool, the delegates are typed as IntPtr’s when in reality they should be typed so it requires so hand updating to straighten the delegates out.
- NSURLRequest in Objective-CObjective-C is NSUrlRequest in MonoTouch. There are a few places where the Objective-C classes don’t map exactly into MonoTouch classes due to naming convention issues.
Step 2: Make the DLL
Generate the bindings by invoking btouch and providing the relevant arguments for your files. The invocation looks something like this:
Step 3: Reference the DLL
Include a reference to the newly generated dll in your MonoTouch project. You will also need to include the static library in the project. For some reason it isn’t enough to just link to the path. You actually need to have the .a file included in the .csproj file. You can set the build action to None.
Step 4: Update the Additional Arguments.
Finally, the MonoTouch project settings need to be updated so the Objective-C library is linked against during compile time. Update the Extra Arguments field in the iPhone Build settings under the Project Options.
You can read more in the official docs under the “Linking the Dependencies” section here
These are the basic steps. It isn’t hard but it isn’t exactly straight forward. My best recommendation is to take a look at my fork of the Localytics project on github and try and reproduce the bindings on your own.
There is a linker bug that Apple introduced in XCode 3.x that causes problems at compile time when trying to link in static libraries with THUMB enabled. You can run a command via the shell to check the dumped output. Make sure to look at line 5, second column. The two byte address is the give away that the library is THUMB) but I don’t have the command off the top of my head. The best way to handle this is to get the full Objective-C source and uncheck the THUMB code option. If you are still using XCode 3.2 then you HAVE to use a static library that has been compiled without THUMB code. The linker bug apparently has been fixed in XCode 4 and you should be able to link against both THUMB and non-THUMB libraries.
You also might want to look into making a fat static library. I do this for most of the bindings I publish so that there is only one static library to link against and you don’t have to hassle with using one library which has been compiled for use with the simulator and one that has been compiled for the device. Checkout this Stack Overflow question for more details on how to make a fat static library.
Updated Decemeber 28, 2011 : Added link to fat static library instructions. Updated August 3, 2020 : This information is widely out of date and not current. Culled deadlinks but left this post for posterity.