错误:从'int(*)(std :: list <myclass *>,int,char **,char **)'到'int(*)的无效转换(void *,int,char **,char ** )'</MyClass的*>

时间:2015-01-29 11:04:59

标签: c++ database list stl sqlite

我会尽量简洁。好吧,我得到了一个AIM为

的项目
  1. 使用C ++访问Sqlite3数据库。
  2. 创建一个具有成员函数的类,用于执行不同类型的SQLite查询。
  3. 完成上述操作后,在main()中使用STL创建一个List容器,并将每个记录作为单独的对象存储在列表中。因此,当用户尝试使用预定义的SQLite查询访问数据库记录时,他将仅访问List容器而不访问数据库。
  4. 在main()函数中完成上述操作后,将所有这些代码传递给其中一个类成员函数。并在main()中调用此特定函数,获取我们将从AIM-(3)
  5. 获得的确切输出

    因此,我正在创建一个位于DBsqlite文件夹(PATH- / DBsqlite3 / foreign_key.db)中的数据库foreign_key.db。

    注意: emp_info 架构如下:

      CREATE TABLE emp_info(
      SR_NO INT ,
      NAME CHAR(32) NOT NULL,
      AGE INT(4) NOT NULL CHECK(AGE > 16),
      SEX CHAR (6) NOT NULL,
      ADDRESS CHAR(70),
      EMPID INT NOT NULL CHECK(EMPID>300) UNIQUE,
      CARDID TEXT NOT NULL UNIQUE,
      SALARY INT CHECK(SALARY>10000) NOT NULL,
      MOBILE_NO INT(16) UNIQUE,
      EMAIL_ID TEXT(32) UNIQUE,
      BDT INT,
      PHOTO BLOB );
    

    emp_info 表中的条目如下(我删除了一些列以使其看起来更好):

     SR_NO  NAME AGE  SEX   ADDRESS    EMPID  CARDID    SALARY    
      1     AAA  35  MALE   A1A2A3A4   301    1111AAA   11111    
      2     BBB  36  FEMALE B1B2B3B4   302    2222BBB   22222    
      3     CCC  37  FEMALE C1C2C3C4   303    3333CCC   33333    
      4     DDD  38  MALE   D1D2D3D4   304    4444DDD   44444    
      5     EEE  39  MALE   E1E2E3E4   305    5555EEE   55555    
      6     FFF  40  MALE   F1F2F3F4   306    6666FFF   66666    
      7     GGG  41  MALE   G1G2G3G4   307    7777GGG   77777    
      8     HHH  42  FEMALE H1H2H3H4   308    8888HHH   88888    
      9     III  43  FEMALE I1I2I3I4   309    9999IIII  99999`
    

    我用C ++编写了以下程序来实现AIM-(1)和AIM-(2)。下面的程序还创建了一个LIST CONTAINER来根据sqlite查询显示值。

    #include <iostream>
    #include <list>
    #include <string>
    #include <sqlite3.h>
    #include <stdlib.h>
    #include <algorithm>
    using namespace std;
    
    class Employee{
    
        int SR_NO;
        int AGE;
        int EMPID;
        int CARDID;
        int SALARY;
        int MOBILE_NO;
        int BDT;
    
        char NAME;
        char SEX;
        char ADDRESS;
    
    };
    
    class sqliteDB{
    
    private:
        int rc;
        sqlite3 *db;
        char *zErrMsg;
        const char *sql;
    
    public:
    
        static int callback(void *NotUsed, int argc, char **argv, char **azColName)
        {
            int i;
            cout << "Number of args= " << argc << endl;
    
            for(i=0; i<argc; i++)
            {
                cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL") << endl;
            }
            cout << endl;
            return 0;
        }
    
    
        bool connectDB()
        {
    
            rc = sqlite3_open("/DBsqlite3/foreign_key.db", &db);
            if( rc )
            {
                cerr << "Can't open database: " << sqlite3_errmsg(db) << endl;
                sqlite3_close(db);
                exit(1);
            }
            else
            {
                std::cout<<"\n\nDatabase opened successfully\n\n";
            }
            return 0;
        }
    
    
        bool allEmp()
        {   //NOTE- BELOW IS LINE 99
            rc = sqlite3_exec(db, "SELECT * FROM emp_info WHERE AGE>40; ", callback, 0, &zErrMsg);
            if( rc!=SQLITE_OK )
            {
                cerr << "SQL error: " << zErrMsg << endl;
                sqlite3_free(zErrMsg);
            }
    
            sqlite3_close(db);
        }
    };
    
    int main()
    {      
    
        list<sqliteDB> employee_info;
       // Read from database from below//
    
          for (int i=0; i<1; i++)
          {
             sqliteDB object2;
             object2.connectDB();
             employee_info.push_back(object2);
          }
    
    
    
        list<sqliteDB>::iterator i;
        for (i = employee_info.begin(); i != employee_info.end(); i++)
        {
            if (! i -> allEmp())
            cout<< i->allEmp() << endl;
         cout << " size of Object inside List is: " << employee_info.size() << '\n';
        }
    
    }
    

    以上结果为:

    Database opened successfully
    
    Number of args= 12
    SR_NO = 7
    NAME = GGG
    AGE = 41
    SEX = MALE
    ADDRESS = G1G2G3G4
    EMPID = 307
    CARDID = 7777GGG
    SALARY = 77777
    MOBILE_NO = 9833446677
    EMAIL_ID = abi@gmail.com
    BDT = 07:08:1947PHOTO = NONE
    
    Number of args= 12
    SR_NO = 8
    NAME = HHH
    AGE = 42
    SEX = FEMALE
    ADDRESS = H1H2H3H4
    EMPID = 308
    CARDID = 8888HHH
    SALARY = 88888
    MOBILE_NO = 9833446688
    EMAIL_ID = abj@gmail.com
    BDT = 08:09:1947
    PHOTO = NONE
    
    Number of args= 12
    SR_NO = 9
    NAME = III
    AGE = 43
    SEX = FEMALE
    ADDRESS = I1I2I3I4
    EMPID = 309
    CARDID = 9999IIII
    SALARY = 99999
    MOBILE_NO = 9833446699
    EMAIL_ID = abk@gmail.com
    BDT = 09:10:1947
    PHOTO = NONE
    
    SQL error: 21
    size of Object inside List is: 1
    

    虽然,我能够看到sqlite查询的3个结果。但是列表中创建的对象只有1(注意 - 在结果的最后一行)。我希望它是3个对象

    我希望List容器将每个有效记录(行)存储为Employee.User类中的单个列表对象,可以访问显示记录的每个字段/列。

    我怎样才能做到这一点?我非常感谢你对此的帮助。如果您展示如何使用基于此问题的示例,我将非常感激。

    谢谢

    更新 - 根据WhozCraig建议的解决方案,我更改了以下内容:

    更改-1 声明另一个列表容器Employee:

    list<Employee*> employee_info;
    

    更改-2 将此列表替换为void *未使用

    static int callback(list<Employee*> employee_info2, int argc, char **argv, char **azColName)

    更改-3 回调函数的主要更改

    Employee *obj_emp = new Employee;
            int i;
            cout << "Number of args= " << argc << endl;
    
                obj_emp->SR_NO=(argv[0] ? argv[0] : "NULL");
                obj_emp->NAME=(argv[1] ? argv[1] : "NULL");
                obj_emp->AGE=(argv[2] ? argv[2] : "NULL");
                obj_emp->SEX=(argv[3] ? argv[3] : "NULL");
                obj_emp->ADDRESS=(argv[4] ? argv[4] : "NULL");
                obj_emp->EMPID=(argv[5] ? argv[5] : "NULL");
                obj_emp->CARDID=(argv[6] ? argv[6] : "NULL");
                obj_emp->SALARY=(argv[7] ? argv[7] : "NULL");
                obj_emp->MOBILE_NO=(argv[8] ? argv[8] : "NULL");
                obj_emp->BDT=(argv[10] ? argv[10] : "NULL");
    
              employee_info2.push_back(obj_emp);
    
         cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL") << endl;
    
            cout << endl;
            return 0;
    

    整个计划

    #include <iostream>
    #include <list>
    #include <string>
    #include <sqlite3.h>
    #include <stdlib.h>
    
    using namespace std;
    
    class Employee{
    
    public:
    
    string SR_NO;
    string AGE;
    string EMPID;
    string CARDID;
    string SALARY; 
    string MOBILE_NO;
    string BDT;
    
    string NAME;
    string SEX;
    string ADDRESS;
    
    };
    
    class sqliteDB{
    
    private:
    int rc;
    sqlite3 *db;
    char *zErrMsg;
    const char *sql;
    
    public:
    
    //  list<Employee> employee_info2; //this line vector<Employee> *employee_info2; defines a pointer to a vector 
                                       //of type Employee and not a vector of type Employee pointers
        list<Employee*> employee_info2;
    
    
        static int callback(list<Employee*> employee_info2, int argc, char **argv, char **azColName)
         {
        Employee *obj_emp = new Employee;
            int i;
            cout << "Number of args= " << argc << endl;
    
    
                obj_emp->SR_NO=(argv[0] ? argv[0] : "NULL");
                obj_emp->NAME=(argv[1] ? argv[1] : "NULL");
                obj_emp->AGE=(argv[2] ? argv[2] : "NULL");
                obj_emp->SEX=(argv[3] ? argv[3] : "NULL");
                obj_emp->ADDRESS=(argv[4] ? argv[4] : "NULL");      
                obj_emp->EMPID=(argv[5] ? argv[5] : "NULL");
                obj_emp->CARDID=(argv[6] ? argv[6] : "NULL");
                obj_emp->SALARY=(argv[7] ? argv[7] : "NULL");
                obj_emp->MOBILE_NO=(argv[8] ? argv[8] : "NULL");
                obj_emp->BDT=(argv[10] ? argv[10] : "NULL");
    
    
              employee_info2.push_back(obj_emp);
    
    
                cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL") << endl;
    
            cout << endl;
            return 0;
          }
    
    
    bool connectDB()
    {
    
          rc = sqlite3_open("/DBsqlite3/foreign_key.db", &db);
          if( rc )
          {
            cerr << "Can't open database: " << sqlite3_errmsg(db) << endl;
            sqlite3_close(db);
            exit(1);
          }
          else
          {
                std::cout<<"\n\nDatabase opened successfully\n\n";
          }
         return 0;
    }
    
    
      bool allEmp()
      {
          sqliteDB object2;
          object2.connectDB();                 
          //NOTE- BELOW IS LINE 99
          rc = sqlite3_exec(db, "SELECT * FROM emp_info WHERE AGE>40; ", callback, 0, &zErrMsg);
          if( rc!=SQLITE_OK )
          {
              cerr << "SQL error: " << zErrMsg << endl;
              sqlite3_free(zErrMsg);
          }
    
          sqlite3_close(db);
    
        }
    };
    
    int main()
    {     
       sqliteDB object1;
       object1.connectDB();
       object1.allEmp();
    }
    

    编译错误后我得到:

    example1.cpp: In member function ‘bool sqliteDB::allEmp()’:
    example1.cpp:99:95: error: invalid conversion from ‘int (*)(std::list<Employee*>, int, char**, char**)’ to ‘int (*)(void*, int, char**, char**)’ [-fpermissive]
           rc = sqlite3_exec(db, "SELECT * FROM emp_info WHERE AGE>40; ", callback, 0, &zErrMsg);
    

    接下来我该怎么办?请帮助

1 个答案:

答案 0 :(得分:0)

您正在尝试将函数指针传递给错误类型的sqlite3_exec函数。您需要将回调的签名更改回原来的方式。

static int callback(void *param, int argc, char **argv, char **azColName)

然后你应该恰当地致电sqlite3_exec。像这样:

rc = sqlite3_exec(db, "SELECT * FROM emp_info WHERE AGE>40; ", callback, &employee_info2, &zErrMsg);

最后,在你的回调中,你将param强制转换回正确的类型。

std::list<Employee*>& employee_info2 = std::reinterpret_cast<std::list<Employee*>&>(*param);