调用与btouch绑定的方法返回对象时,抛出System.InvalidCastException异常. MonoTouch错误? [英] Exception System.InvalidCastException when calling a method bound with btouch that returns an object. MonoTouch bug?

查看:63
本文介绍了调用与btouch绑定的方法返回对象时,抛出System.InvalidCastException异常. MonoTouch错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to bind the types of an Objective-C library using btouch. I have managed to compile my API definition file with btouch and have successfully called methods that return no parameters or which return basic parameters like string or integer. However, when I try call methods that return instance objects for other classes defined in the API definition file, I get an exception System.InvalidCastException thrown. So in the example listing that follows, the static OpenConnection method of the UltraliteManager class throws this exception when called from a MonoTouch project.

这是Objective-C头文件:

This is the Objective-C header file:

#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的实现(仅显示相关实现):

This is the Objective-C implementation (abridged to show just the relevant implementations):

@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 nil; 替换行 return connwrap; ),则该方法返回而不会抛出一个例外.因此在我看来,此异常与将UltraliteConnection对象返回到MonoTouch有关.

I have found that if I return NULL from my implementation of openConnection (ie. replace the line return connwrap; with return nil;) then the method returns without throwing an exception. So it seems to me that this exception has to do with returning of the UltraliteConnection object to MonoTouch.

任何人都知道导致此问题的原因以及如何解决该问题?

Anyone have any idea what is causing this problem and how I can resolve it?

推荐答案

我设法解决了这个问题,它的确确实是MonoTouch中的错误.我的解决方法是使用 outdir 参数集调用 btouch ,然后将生成的C#文件包含在我的项目中.因此,不要这样做:

I have managed to work around this issue and it does indeed seem to be a bug in MonoTouch. My workaround was to call btouch with the outdir parameter set and then include the generated C# files in my project. So, instead of doing this:

btouch ultralite.cs枚举.cs

我做到了:

btouch ultralite.cs enum.cs -outdir =.

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

This generated files in two folders ObjCRuntime and Ultralite (the name of my namespace). I removed the ultralite.dll from the references of my project, and instead copied and included the files from these two directories that btouch generated. With the C# files included instead of the dll as reference, the OpenConnection method that I referred to in my question executed correctly and returned the connection object.

我从未对我的Objective-C包装器库或API定义文件进行过任何更改,因此,这肯定是btouch中的错误.或者也许我在最初对btouch的调用中缺少其他必需的参数.也许来自MonoTouch的人可能对此有所了解.

I never made any changes to my Objective-C wrapper library, nor the API definition file, so it definitely seems to be a bug in btouch. Or maybe I was missing some other required argument in my original call to btouch. Maybe someone from MonoTouch could shed some light on this.

但是,最重要的是,我的库终于被导入并且可以在MonoTouch中正常工作. :)我希望这些信息对遇到此问题的其他人有所帮助.

But, bottom line, my library is finally imported and working correctly in MonoTouch. :) I hope that this information is helpful to anyone else who encounters this problem.

这篇关于调用与btouch绑定的方法返回对象时,抛出System.InvalidCastException异常. MonoTouch错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆