调用与 btouch 绑定并返回对象的方法时出现异常 System.InvalidCastException。单触错误?
Posted
技术标签:
【中文标题】调用与 btouch 绑定并返回对象的方法时出现异常 System.InvalidCastException。单触错误?【英文标题】:Exception System.InvalidCastException when calling a method bound with btouch that returns an object. MonoTouch bug? 【发布时间】:2011-03-17 10:10:59 【问题描述】:我正在尝试使用 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 nil; 替换行 return connwrap;)然后该方法返回而不抛出一个例外。所以在我看来,这个异常与将 UltraliteConnection 对象返回给 MonoTouch 有关。
有人知道是什么导致了这个问题,我该如何解决?
【问题讨论】:
如果需要,我的 MonoTouch 版本号是 3.2.4.9004 EVALUATION。此外,我发现此链接指向似乎描述了我遇到的问题的错误报告:mail-archive.com/mono-bugs@lists.ximian.com/msg67928.html 【参考方案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 中正常工作。 :) 我希望这些信息对遇到此问题的其他人有所帮助。
【讨论】:
【参考方案2】:我认为问题在于本机 UltraliteConnection
对象正在使用特定方法进行初始化 - initWithULConnection:
。
既然是这种情况,您必须在UltraliteConnection
对象的 API 定义中实现构造函数:
[Export ("initWithULConnection:")]
IntPtr Constructor (ULConnection connbase);
当然,您还需要绑定 ULConnection 对象才能使其工作。
你有MonoTouch的评估版没关系,它和商业版一样,你不能用它部署到设备和App Store。
【讨论】:
嗯...我不确定...不过尝试一下。 感谢您的回复,迪米特里斯。不过,我看不出这有什么帮助,因为我实际上并不希望能够从 MonoTouch 构造这个 UltraliteConnection 对象。事实上,即使构造函数在那里,也不能从 MonoTouch 中使用,因为作为参数传入的基类是 Ultralite C++ 库中的一个连接对象,它只能在我的 Objective-C 包装器中使用图书馆。 这就是你征服 SQL Ultralite 库的方式吗?我将使用 SWIG 亲自尝试一下,对您的发现感到好奇。以上是关于调用与 btouch 绑定并返回对象的方法时出现异常 System.InvalidCastException。单触错误?的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin Studio btouch 不支持的字段类型:NSUuid