我正在尝试使用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有关。
任何人都知道造成这个问题的原因以及我如何解决它?
答案 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。