连续错误21:“库程序不按顺序调用”

时间:2016-07-12 13:30:50

标签: c++ sqlite

我正在围绕Sqlite C函数编写一个简单的包装类。环境是Ubuntu 14_04,gcc 4.8.4的版本,我通过apt-get安装了libsqlite-dev,我相信这是版本3.8.2。

问题是:如果我调用多个函数(c'torexec),则测试失败。如果我将我的代码包装的sqlite函数(_open_exec)函数放在一个函数中(我在构造函数中尝试过),那么它就会传递。失败是

  

错误:21 msg:库程序不按顺序调用

失败的单元测试是:

TEST_FIXTURE(DatabaseFixture, TryToCreateATable)
{
    database db(test);
    REQUIRE CHECK(db);
    CHECK(db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
    std::cout << db.error() << std::endl;
}

包装类如下。

database(const std::string& filename)
    : connected_(false), database_(nullptr)
{
    if (sqlite3_open(filename.c_str(), &database_) != SQLITE_OK)
    {
        const std::runtime_error ex(error());
        sqlite3_close(database_);
        throw ex;
    }
    connected_ = true;
}

bool exec(const std::string& query)
{
    assert(connected_ != false && "The connected is false");
    assert(database_ != nullptr && "The db_ is null");
    assert(!query.empty() && "The string is empty");
    sql_statement call;
    assert(call.statement == nullptr && "The call is not null");
    int result = sqlite3_exec(database_, query.c_str(), NULL, NULL, NULL);
    // int result = sqlite3_prepare_v2(database_, query.c_str(), -1, &call.statement, nullptr);
    if (result != SQLITE_OK)
    {
        std::cout << "err: " << result << " msg: " << error() << std::endl;
        return false;
    }
    return true;
}

sql_statement_stmt的一个小包装器,它将指针初始化为null并在析构函数中调用_finalize。 “error()' returns the string from _ errmsg`。

正如您所看到的,我尝试使用_prepare_v2,但失败并出现同样的错误。有不同的libsqlite版本会有所不同 - 我会期望它将无法编译?你如何检查libsqlite是否与安装的版本匹配?它应该有所不同 - 我认为不应该这样吗?

更新:我创建了一个新VM,并以全新安装的Ubuntu 14_04开始。通过apt-get按以下顺序获得所需的一切:Git,CMake,g ++,sqlite3,libsqlite3-dev。仍然表现出同样的问题。 UPDATE2 :我使用16_04创建了一个新的VM。安装了我以前做过的所有事情,除了g ++(已经安装)和相同的顺序。仍然表现出同样的问题。由于SQL的版本号不同,我认为可以排除吗?

2 个答案:

答案 0 :(得分:2)

CHECK(db)宏调用扩展为UnitTest::Check(db) - 声明为:

   template< typename Value >
   bool Check(Value const value)
   {
      return !!value; // doing double negative to avoid silly VS warnings
   }

这意味着复制db以便按值传递。

如果你有一个默认的拷贝构造函数,你的析构函数使用它的数据库指针关闭数据库连接,我很确定这会产生你所看到的效果。

已编辑添加:https://github.com/unittest-cpp/unittest-cpp/issues/7

答案 1 :(得分:0)

看起来问题与UnitTest ++和CHECK(db)宏与代码奇怪地交互有关。删除该行允许单元测试完成并通过。我将进一步调查并将问题发布到UnitTest ++项目。