我无法使用我在 c 中添加的新参数传递回调函数 [英] I'm not able to pass a callback function with a new argument i added in c

查看:32
本文介绍了我无法使用我在 c 中添加的新参数传递回调函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何将变量传递给回调以在此函数中执行某些操作(打印 json 输出).

I don't know how to pass a variable into a callback to do some stuff (print json output) inside this function.

在示例代码中,我不需要传递其他函数,但是对于 sqlite3,我想我必须在回调中执行此操作,如果我做错了,请告诉我.

In sample code there is no other functions i need to pass but with sqlite3 I think I have to do this in the callback, tell me if i'm doing wrong.

回调在我的代码中的 sendhosts() 函数中调用.

The callback is called in sendhosts() function in my code.

我收到此错误:

在函数‘sendhosts’中:sample.c:85:48: 错误:函数回调"的参数太少rc = sqlite3_exec(db, "SELECT * FROM hosts;", callback(req), 0, &zErrMsg);

In function ‘sendhosts’: sample.c:85:48: error: too few arguments to function ‘callback’ rc = sqlite3_exec(db, "SELECT * FROM hosts;", callback(req), 0, &zErrMsg);

原始代码是:

#include <stdio.h>
#include <sqlite3.h>

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
  int i;
  for(i=0; i<argc; i++){
    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  }
  printf("\n");
  return 0;
}  
int main(int argc, char **argv){
  sqlite3 *db;
  char *zErrMsg = 0;
  int rc;

  if( argc!=3 ){
    fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
    return(1);
  }
  rc = sqlite3_open(argv[1], &db);
  if( rc ){
    fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
    sqlite3_close(db);
    return(1);
  }
  rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
  if( rc!=SQLITE_OK ){
    fprintf(stderr, "SQL error: %s\n", zErrMsg);
    sqlite3_free(zErrMsg);
  }
  sqlite3_close(db);
  return 0;
}

我的代码是:

#include <sys/types.h> /* size_t, ssize_t */
#include <stdarg.h> /* va_list */
#include <stddef.h> /* NULL */
#include <stdint.h> /* int64_t */
#include <stdlib.h>
#include <string.h> /* memset */
#include <stdio.h>

#include <kcgi.h>
#include <kcgihtml.h>
#include <sqlite3.h>
enum    page {
    PAGE_HOSTS,
    PAGE__MAX
};
enum    key {
    KEY_INTEGER, 
    KEY_FILE,
    KEY_PAGECOUNT,
    KEY_PAGESIZE,
    KEY__MAX
};
struct  tstrct {
    struct khtmlreq  req;
    struct kreq *r;
};
typedef void (*disp)(struct kreq *);
static void sendhosts(struct kreq *);

static const disp disps[PAGE__MAX] = {
    sendhosts, /* PAGE_SENDDATA */
};
static const struct kvalid keys[KEY__MAX] = {
    { kvalid_int, "integer" }, /* KEY_INTEGER */
    { NULL, "file" }, /* KEY_FILE */
    { kvalid_uint, "count" }, /* KEY_PAGECOUNT */
    { kvalid_uint, "size" }, /* KEY_PAGESIZE */
};
static const char *const pages[PAGE__MAX] = {
    "sendhosts" /* PAGE_SENDDATA */
};
static void
resp_open(struct kreq *req, enum khttp http)
{
    enum kmime   mime;
    if (KMIME__MAX == (mime = req->mime))
        mime = KMIME_APP_OCTET_STREAM;

    khttp_head(req, kresps[KRESP_STATUS], 
        "%s", khttps[http]);
    khttp_head(req, kresps[KRESP_CONTENT_TYPE], 
        "%s", kmimetypes[mime]);
    khttp_body(req);
}
static int callback(struct kreq *req, int argc, char **argv, char **azColName){
    char        *page;
    struct khtmlreq  r;
    resp_open(req, KHTTP_200);
    khtml_open(&r, req, 0);
  int i;
  for(i=0; i<argc; i++){
    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    struct khtmlreq r;
    khtml_puts(&r, "OK");
  }
    khtml_close(&r);
    free(page);
}
static void
sendhosts(struct kreq *req)
{
    sqlite3 *db;
    char *zErrMsg = 0;
    int rc;
    rc = sqlite3_open("/var/www/MaSSH/databases/massh.db", &db);
    if(rc){
        sqlite3_close(db);
    }
    rc = sqlite3_exec(db, "SELECT * FROM hosts;", callback(req), 0, &zErrMsg);
    if(rc!= SQLITE_OK){
        sqlite3_free(zErrMsg);
    }
    sqlite3_close(db);
}
int
main(void)
{
    struct kreq  r;
    enum kcgi_err    er;

    /* Set up our main HTTP context. */

    er = khttp_parse(&r, keys, KEY__MAX, 
        pages, PAGE__MAX, PAGE_HOSTS);

    if (KCGI_OK != er)
        return(EXIT_FAILURE);

    /* 
     * Accept only GET, POST, and OPTIONS.
     * Restrict to text/html and a valid page.
     * If all of our parameters are valid, use a dispatch array to
     * send us to the page handlers.
     */

    if (KMETHOD_OPTIONS == r.method) {
        khttp_head(&r, kresps[KRESP_ALLOW], 
            "OPTIONS GET POST");
        resp_open(&r, KHTTP_200);
    } else if (KMETHOD_GET != r.method && 
           KMETHOD_POST != r.method) {
        resp_open(&r, KHTTP_405);
    } else if (PAGE__MAX == r.page || 
           KMIME_TEXT_HTML != r.mime) {
        resp_open(&r, KHTTP_404);
    } else
        (*disps[r.page])(&r);

    khttp_free(&r);
    return(EXIT_SUCCESS);
}

推荐答案

您的回调签名

static int callback(struct kreq *req, int argc, char **argv, char **azColName)

错了.应该是

static int callback(void *ptr, int argc, char **argv, char **azColName) {
    struct kreq *req = (struct kreq *)ptr;

回调的签名应该与函数指针的格式完全匹配,对于sqlite3_execis int (*callback)(void *, int, char **, char **).

The callback's signature should exactly match the function pointer's format, which, for sqlite3_exec, is int (*callback)(void *, int, char **, char **).

还有这个

rc = sqlite3_exec(db, "SELECT * FROM hosts;", callback(req), 0, &zErrMsg);

应该是

rc = sqlite3_exec(db, "SELECT * FROM hosts;", callback, req, &zErrMsg);

callback(req) 调用了callback,这不是你想要的;您正在尝试将函数指针传递给函数,这仅通过函数的名称来完成.

callback(req) calls callback, which is not what you want; you're trying to pass a function pointer to a function, which is done with just the function's name.

这篇关于我无法使用我在 c 中添加的新参数传递回调函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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