C/C ++中的SQLite. sqlite3_exec:在回调函数中设置的参数指向空字符串 [英] SQLite in C/C++. sqlite3_exec: parameter set in callback function is pointing to an empty string

查看:164
本文介绍了C/C ++中的SQLite. sqlite3_exec:在回调函数中设置的参数指向空字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试一些真正的基础-使用 C/C ++返回SELECT语句的结果SQLite的界面.我的数据表只有两个字段-键(varchar)和值(文本).

I'm trying to something really basic - returning the result of the SELECT statement using C/C++ interface for SQLite. My Data table has only two fields - key (varchar) and value (text).

给出键,我的目标是通过查询SQLite数据库返回值.我传递给* sqlite3_exec *-* select_callback *函数以及 param (char *). param 已成功在* select_callback *中设置为正确的值.但是,在调用* sqlite3_exec *之后,param指向一个空字符串(尽管指向相同的内存).

Given the key, my goal is to return the value by querying the SQLite database. I pass to *sqlite3_exec* - *select_callback* function as well as param (char *). The param is successfully set to the correct value within *select_callback*. However, after calling *sqlite3_exec* param points to an empty string (despite pointing to the same memory).

任何想法都出了什么问题以及如何解决此问题? * sqlite3_exec *是否在后台为 param 分配内存?

Any idea what's going wrong and how to fix this? Does *sqlite3_exec* deallocate memory for param behind the scenes?

提前谢谢!

// given the key tid returns the value
void getTypeByID(sqlite3 * db, string tid)
{
    string sql_exp_base = "select value from Data where key=''";
    int len = (int)sql_exp_base.size() + (int)tid.size() + 10;
    char * sql_exp = new char[len];
    sprintf(sql_exp, "select value from Data where key='%s'", tid.data());
    sql_exec(db, sql_exp);
}

// This is the callback function to set the param to the value
static int select_callback(void * param, int argc, char **argv, char **azColName)
{
    if(argc == 0) return 0;
    char * res = (char *)param;
    res = (char *) realloc(res, sizeof(*res));
    res = (char *) malloc(strlen(argv[0]) + 1);
    strcpy(res, argv[0]);
    printf("%s\n", res); // {"name": "Instagram Photo", url: "http://instagram.com"}
    return 0;
}

// execute the SQL statement specified by sql_statement
void sql_exec(sqlite3 * db, const char * sql_statement)
{
    char * zErrMsg = 0;
    char * param = (char *)calloc(1, sizeof(*param));
    int rc = sqlite3_exec(db, sql_statement, select_callback, param, &zErrMsg);
     printf("%s\n", param);

参数应为{"name":"Instagram图片",URL:"http://instagram.com"},但出于某些原因是空字符串!

    if(rc != SQLITE_OK)
    {
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
    }
}

推荐答案

您正在将指向新分配的内存的指针写入res,但是该变量是select_callback内部的局部变量,因此sql_exec不会知道这一点. param参数也是如此:它只是sqlite3_exec的第四个参数的副本.

You are writing the pointer to the newly allocated memory into res, but that variable is a local variable inside select_callback, so sql_exec will not know about it. The same applies to the param parameter: it is just a copy of sqlite3_exec's fourth parameter.

为确保可以看到对字符串所做的更改,必须将指针传递给字符串本身(在C中为指针,或者在C ++中为string对象),类似于错误消息. 对于C:

To ensure that your changes to the string are seen, you have to pass a pointer to the string itself (which is a pointer in C, or could be a string object in C++), similar to the error message. For C:

char *result_str = ...;
rc = sqlite3_exec(..., &result_str, ...);
...
int callback(void *param, ...)
{
    char **result_str = (char **)param;
    *result_str = (char *)realloc(*result_str, ...);
    strcpy(*result_str, ...);
}


注意:当tid字符串包含引号或其他控制字符时,或者当您尝试搜索 sqlite3_mprintf 格式化和分配SQL字符串,或者更好地使用参数.


Note: You will get problems when the tid string contains quotes or other control characters, or when you try to search for Bobby Tables. Use sqlite3_mprintf to format and allocate the SQL string, or better use parameters.

这篇关于C/C ++中的SQLite. sqlite3_exec:在回调函数中设置的参数指向空字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆