Исключение System.InvalidCastException при вызове метода, связанного с btouch, который возвращает объект. Ошибка MonoTouch? - PullRequest
1 голос
/ 17 марта 2011

Я пытаюсь связать типы библиотеки Objective-C, используя btouch. Мне удалось скомпилировать мой файл определения API с помощью btouch и я успешно вызвал методы, которые не возвращают параметров или которые возвращают базовые параметры, такие как строка или целое число. Однако, когда я пытаюсь вызвать методы вызова, которые возвращают объекты экземпляра для других классов, определенных в файле определения API, я получаю исключение System.InvalidCastException . Таким образом, в следующем примере списка статический метод OpenConnection класса UltraliteManager вызывает это исключение при вызове из проекта 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);
    }
}

Я обнаружил, что если я возвращаю NULL из моей реализации openConnection (т. Е. Заменим строку return connwrap; на return nil; ), то метод вернется без выброса исключения , Поэтому мне кажется, что это исключение связано с возвратом объекта UltraliteConnection в MonoTouch.

Кто-нибудь знает, что вызывает эту проблему и как я могу ее решить?

Ответы [ 2 ]

1 голос
/ 18 марта 2011

Мне удалось обойти эту проблему, и она действительно является ошибкой в ​​MonoTouch.Мой обходной путь состоял в том, чтобы вызвать btouch с набором параметров outdir и затем включить сгенерированные файлы C # в мой проект.Итак, вместо этого:

btouch ultralite.cs enum.cs

Я сделал:

btouch ultralite.cs enum.cs -outdir =.

Это сгенерированные файлы в двух папках ObjCRuntime и Ultralite (имя моего пространства имен).Я удалил ultralite.dll из ссылок моего проекта и вместо этого скопировал и включил файлы из этих двух каталогов, которые сгенерировал btouch.С файлами C #, включенными вместо dll в качестве ссылки, метод OpenConnection , на который я ссылался в своем вопросе, был выполнен правильно и возвратил объект подключения.

Я никогда не вносил никаких изменений в свою цель-C библиотека обертки, ни файл определения API, так что это определенно ошибка в btouch.Или, может быть, я упустил какой-то другой обязательный аргумент в моем первоначальном вызове btouch.Возможно, кто-то из MonoTouch мог бы пролить свет на это.

Но, суть в том, что моя библиотека наконец-то импортирована и работает правильно в MonoTouch.:) Я надеюсь, что эта информация будет полезна всем, кто сталкивается с этой проблемой.

0 голосов
/ 17 марта 2011

Я думаю, что проблема в том, что собственный UltraliteConnection объект инициализируется с помощью определенного метода - initWithULConnection:.

Поскольку это так, вы должны реализовать конструктор в своем определении APIUltraliteConnection объект:

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

И, конечно, вам также необходимо привязать объект ULConnection, чтобы это работало.

Неважно, что у вас есть оценочная версияMonoTouch, он такой же, как коммерческий, вы просто не можете развернуть его на устройствах и в App Store с его помощью.

...