I have been working on integrating a third party library build with native languages (objective c / c++) into a Xamarin application and I though I’d share my learnings
Some information about the library
- I had couple of static libraries .a files.
- I had two frameworks .framework files
- I had four bundle folders .bundle folders.
- Xamarin Studio on MAC.
- XCode Command line tools.
Find out what architectures you will support
First thing we want to know. Is against which architecture these .a files are build against.
There is a command line tool called “lipo” that you can use to detect the architectures of the .a file like this
lipo -info xx.a
For me this tool was giving incorrect result so I had to use Clang like this
clang -arch armv7 -gmodules xx.a
Then what we need to do is to try and test what architectures we need to support if the architecture is not supported in the .a file you we will get
“Undefined symbols for architecture arm64”
Create your binding project
I will not go through how to create a brand new binding project you can follow the Walkthrough from Xamarin
This walkthrough is great for straight forward scenarios but in my case I had to do extra steps.
After finishing your project and adding the .a files open the .cs file generated , it should look like this at the beginning.
[assembly: LinkWith ( “RoverLink.a”, SmartLink = true, ForceLoad = true)]
Then what we need to do is from prev step add the supported architectures
[assembly: LinkWith ( “RoverLink.a”,LinkTarget.ArmV7s | LinkTarget.ArmV7, SmartLink = true, ForceLoad = true)]
if the library build with c++ then it should be like this
[assembly: LinkWith ( “RoverLink.a”,LinkTarget.ArmV7s | LinkTarget.ArmV7, SmartLink = true, IsCxx = true, ForceLoad = true)]
Now you want to see what frameworks does your library depend on (this is different from the two frameworks file that I have at the beginning ) and then add them like this
[assembly: LinkWith ( “RoverLink.a”,LinkTarget.ArmV7s | LinkTarget.ArmV7, SmartLink = true, IsCxx = true, ForceLoad = true, Frameworks = “CoreGraphics Foundation UIKit SystemConfiguration CoreText QuartzCore MessageUI”)]
if your library depend on a dynamic libraries .dylib like libz.dylib then add them like this
[assembly: LinkWith ( “RoverLink.a”,LinkTarget.ArmV7s | LinkTarget.ArmV7, SmartLink = true, IsCxx = true, ForceLoad = true, Frameworks = “CoreGraphics Foundation UIKit SystemConfiguration CoreText QuartzCore MessageUI” ,LinkerFlags = “-ObjC -all_load -lstdc++ -lz”)]
So what is it all about.
- -ObjC is for objective c
- -isdc++ for C++
- The library called libz.dylib then add it like that –lz
If you have multiple .a files you need to do the same by adding them to the same project.
Now comes to the frameworks. Inside the framework folder you will find Headers folder and executable file with no extension.What you will need to do is rename this executable and add .a extension and treat it like the previous files.
And for the Header files in the Headers folder we will use Objective Sharpie to generate the Api interface as per the walkthrough.
Using your binding project
As per the walkthrough you need to add a reference to your generated dll. But what I want to talk about is how to use the Bundle folders that came with the SDK.
This was a bit confusing because inside the bundle folder there were some .xib files and I thought I need to treat them differently but turns out not.
So what you need to do is just drag the bundle folder , or Add Existing Folder and select your bundle folder , But make sure you add it to the root of the project.
After that if your SDK is looking for some assets in there bundle folder it should find it.