Binding ObjectiveC Class to C# problem
The monotouch project describes how to bind Objective-C Types for use with MonoTouch. We failed to do this for the AdMob library (see also the monotouch-binding-for-admob blog at sabonrai dot wordpress dot com.
So we decided to create the smallest possible test project. We wrote a simple objc class with two simple methods, one that returns a string, and one that returns an integer.
Here's the TstLib.h:
#import <Cocoa/Cocoa.h>
@interface TstCls : NSObject {
}
- (NSString *) Version;
- (int) GimmeAnInt;
@end
and the TstLib.m file:
#import "TstCls.h"
@implementation TstCls
- (NSString *) Version {
return @"I ain't got a version, I'm a poor lonesome cowboy...";
}
- (int) GimmeAnInt {
return 110646;
}
@end
We've got a little objc console project to validate this library. Here's the code:
#import <Cocoa/Cocoa.h>
#import "../TstLib/TstCls.h"
int main(int argc, char *argv[])
{
TstCls* tstCls = [[TstCls alloc] init];
NSLog(@"version = %@", [tstCls Version]);
NSLog(@"the int = %d", [tstCls GimmeAnInt]);
return NSApplicationMain(argc, (const char **) argv);
}
So, let's define a binding file for the btouch utility.
using MonoTouch.Foundation;
namespace TstLib {
[BaseType (typeof (NSObject))]
interface TstCls {
[Export ("Version")]
string Version ();
[Export ("GimmeAnInt")]
int GimmeAnInt ();
}
}
We then create a libTstLib.a and a TstLib.dll file with the btouch utility:
/Developer/MonoTouch/usr/bin/btouch -o TstLib.dll TstCls.cs
We now create a new Monotouch window based iphone app 'ApiTest', add a Lib directory with the libTstLib.a and the TstLib.dll files, add a reference to this TstLib.dll and integrate our TstLib into the Main.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using TstCls;
namespace ApiTest
{
// -gcc_flags "-L${ProjectDir}/Lib -lTstLib -ObjC"
// or
// -gcc_flags "-L${ProjectDir}/Lib -lTstLib -force_load ${ProjectDir}/Lib/libTstLib.a"
public class Application
{
static void Main (string[] args)
{
UIApplication.Main (args);
}
}
// The name AppDelegate is referenced in the MainWindow.xib file.
public partial class AppDelegate : UIApplicationDelegate
{
// This method is invoked when the application has loaded its UI and its ready to run
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// If you have defined a view, add it here:
// window.AddSubview (navigationController.View);
TstLib.TstCls tstCls = new TstLib.TstCls ();
Console.WriteLine ("TstLib.TstCls.Version() -> '{0}'", tstCls.Version ());
Console.WriteLine ("TstLib.TstCls.GimmeAnInt() -> '{0}'", tstCls.GimmeAnInt ());
window.MakeKeyAndVisible ();
return true;
}
// This method is required in iPhoneOS 3.0
public override void OnActivated (UIApplication application)
{
}
}
}
This little project runs without the two Console.Writeline statements. It crashes without any output as soon as one of the Console.WriteLine statements is executed.
We've tried to be as concise as possible, still providing enough info to recreate the test case. We're very willing to provide any additional info to help fix this.
Does anybody see why this does not work as expected? We've limited ourselves to the bare minimum to test whether we can provide and use a binding for a minimal ObjC class.
Unfortunately it fails. And it fails in the same way as the MT_SampleAdMob project described in the monotouch-binding-for-admob blog.
Our little project uses the btouch approach described at monotouch dot net under heading Binding_New_Objective-C_Types whereas the MT_SampleAdMob project uses the 'manual' approach described at the same location.
Both approaches fail in a similar matter. As soon as a class or instance method is called, the app just crashes without any output.
We've got no idea what can be done to pinpoint this problem and come to a solution. Monotouch provides c# bindings for many of the ObjC classes, so it must be possible. We've carefully studied the MonoTouch docs referenced above. We fail to see where either the MT_SampleAdMob or this btouch approach would deviate from the prescribed procedure, and yet both fail!
So really, we desperately need some help here...