调用与返回对象的btouch绑定的方法时出现异常System.InvalidCastException。 MonoTouch错误?

时间:2011-03-17 10:10:59

标签: xamarin.ios monodevelop

我正在尝试使用btouch绑定Objective-C库的类型。我已经设法用btouch编译我的API定义文件,并成功调用了不返回参数或返回基本参数(如字符串或整数)的方法。但是,当我尝试调用返回API定义文件中定义的其他类的实例对象的方法时,我得到一个异常 System.InvalidCastException 抛出。因此,在随后的示例列表中, UltraliteManager 类的静态 OpenConnection 方法在从MonoTouch项目调用时会抛出此异常。

这是Objective-C头文件:

#import <Foundation/Foundation.h>

@interface UltraliteConnection : NSObject {
@private
    void * ulconnection;
}
- (id) initWithULConnection: (void*) connect;
- (void) dealloc;
- (void) close;
- (void) executeStatement: (NSString*) sql;
@end

@interface UltraliteManager: NSObject {}
+ (void) initialize;
+ (void) fini;
+ (UltraliteConnection*) openConnection: (NSString*)connectionParms;
@end

这是Objective-C实现(仅显示相关实现):

@implementation UltraliteConnection
- (id) initWithULConnection: (void*) connect
{
    [super init];
    ulconnection = connect;
    [self retain];
    return self;
}
- (void) dealloc 
{
    [super dealloc];
}
- (void) close
{
    ULError error;
    ((ULConnection*) ulconnection)->Close(&error);
    [self release];
}
@end

@implementation UltraliteManager
+ (UltraliteConnection*) openConnection: (NSString*)connectionParms
{
    ULError error;
    ULConnection * connbase;
    UltraliteConnection * connwrap;
    connbase = ULDatabaseManager::OpenConnection([connectionParms UTF8String],
                                                 &error, 
                                                 NULL);
    connwrap = [[UltraliteConnection alloc] initWithULConnection:connbase];
    [connwrap release];
    return connwrap;
}
@end

这是API定义文件:

using MonoTouch.Foundation;

namespace Ultralite {
    [BaseType (typeof (NSObject))]
    interface UltraliteConnection {
        [Export("close")]
        void Close ();
        [Export("executeStatement:")]
        void ExecuteStatement(string sql);
    }
    [BaseType (typeof (NSObject))]
    interface UltraliteManager {
        [Static, Export ("initialize")]
        string Initialize ();
        [Static, Export ("fini")]
        void Fini ();
        [Static, Export ("openConnection:")]
        UltraliteConnection OpenConnection (string connectionParms);
    }
}

我发现如果我从openConnection的实现中返回NULL(即替换行 return connwrap; return nil; ),则该方法返回而不抛出一个例外。所以在我看来,这个异常与将UltraliteConnection对象返回到MonoTouch有关。

任何人都知道造成这个问题的原因以及我如何解决它?

2 个答案:

答案 0 :(得分:1)

我设法解决了这个问题,它确实似乎是MonoTouch中的一个错误。我的解决方法是使用 outdir 参数集调用 btouch ,然后在我的项目中包含生成的C#文件。所以,而不是这样做:

btouch ultralite.cs enum.cs

我做了:

btouch ultralite.cs enum.cs -outdir =。

这生成了两个文件夹 ObjCRuntime Ultralite (我的命名空间名称)的文件。我从项目的引用中删除了 ultralite.dll ,而是复制并包含了btouch生成的这两个目录中的文件。如果包含C#文件而不是dll作为引用,我在问题中引用的 OpenConnection 方法正确执行并返回连接对象。

我从未对Objective-C包装器库或API定义文件进行任何更改,所以它肯定是btouch中的一个错误。或许我在原来打电话给btouch时遗漏了一些其他必要的论点。也许来自MonoTouch的人可以对此有所了解。

但是,底线,我的库最终导入并在MonoTouch中正常工作。 :)我希望这些信息对遇到此问题的任何人都有帮助。

答案 1 :(得分:0)

我认为问题在于使用特定方法初始化本机UltraliteConnection对象 - initWithULConnection:

由于是这种情况,您必须在UltraliteConnection对象的API定义中实现构造函数:

[Export ("initWithULConnection:")]  
IntPtr Constructor (ULConnection connbase);

当然,您还需要绑定ULConnection对象才能使其正常工作。

您拥有MonoTouch的评估版本并不重要,它与商业广告相同,您无法使用它部署到设备和App Store。