将C ++ API转换为托管代码API

时间:2011-03-14 13:23:09

标签: iphone c++ objective-c xamarin.ios

我试图在Objective-C类中包装一个C ++库,以便使用btouch导入MonoTouch。我试图了解如何翻译API以便在托管环境中使用。具体来说,如何处理接受局部变量指针的方法,如下例中的ULDatabaseManager :: OpenConnection静态方法:

class UL_CLS_SPEC ULError {
    public:
    ULError();

    /* Gets the error code (SQLCODE) for the last operation. */
    inline an_sql_code GetSQLCode() const {
        return _info.sqlcode;
    }
}

class UL_CLS_SPEC ULDatabaseManager {
    public:
    /* Initializes the UltraLite runtime. */
    static bool Init();

    /* Finalizes the UltraLite runtime. */
    static void Fini();

    /* Opens a new connection to an existing database. */
    static ULConnection * OpenConnection(
        const char * connParms,
        ULError * error = UL_NULL);
}

从Objective-C开始,这个C ++ API将被调用如下:

- (void)openConnection {
    if (ULDatabaseManager::Init()) {
        const char * connectionParms;
        ULConnection * conn = nil;
        ULError error;

        connectionParms = [self getConnectionParms];

        // Attempt connection to the database
        conn = ULDatabaseManager::OpenConnection(connectionParms, &error);

        // If database file not found, create it and create the schema
        if (error.GetSQLCode() == SQLE_ULTRALITE_DATABASE_NOT_FOUND) {       
            // Handle error
        }                
    }
}

在此API中,OpenConnection静态方法的调用者负责定义ULError变量并将其作为引用指针参数传递。这种范例似乎不能很好地转换为托管环境,或者至少对我而言,让调用者负责实例化ULError对象似乎并不正确。将此API转换为Objective-C类的最佳实践是什么?哪个类负责创建和销毁ULError对象?

我希望我的问题有道理,因为我对C ++和Objective-C(以及MonoTouch)非常陌生,所以我仍然不知道我不知道什么! :)此刻感觉有点偏离我的深度。所以我希望对有助于解释如何包装C ++ API的好文章提出任何建议或参考。

PS:我知道这个问题主要涉及C ++和Objective-C,但我将MonoTouch作为一个标签,以防有人使用btouch导入Objective-C类的经验提供了一些建议。

2 个答案:

答案 0 :(得分:1)

我认为你最好的解决方案是围绕C ++类创建一个objective-c类。然后用btouch绑定应该非常简单。

答案 1 :(得分:0)

我解决这个问题的方法是使用btouch更改暴露给Monotouch的API。具体来说, OpenConnection 等方法只需要 connectionParms ,而不是指向错误类的指针。然后我在open方法中进行了错误检查,如果发生错误则返回 nil 。在包装器类中,我还保留了一个名为 lastConnectionError 的ULError对象,我的C ++代码通过 OpenConnection C ++调用传递了一个指向该对象的指针。我在我的包装器类 GetLastConnectionError 中包含了一个单独的方法,它返回了一个表示不同错误状态的枚举