将C++ API翻译成托管代码API

3

我正在尝试用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个回答

1

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


这正是我所采取的路线。我正在用Objective-C库包装C++ API,然后使用btouch进行绑定。我已经用部分C++ API制作了概念验证。不过,我的主要问题是如何转换返回结构指针的方法,比如我提供的示例中的_ULDatabaseManager :: OpenConnection_静态方法。对于这样的方法,最好的转换方法是什么? - BruceHill

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接