Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;如何通过回调方法访问成员变量_C++_Sqlite_Callback_Static Methods_Friend - Fatal编程技术网

C++ C++;如何通过回调方法访问成员变量

C++ C++;如何通过回调方法访问成员变量,c++,sqlite,callback,static-methods,friend,C++,Sqlite,Callback,Static Methods,Friend,我使用SQLite的sqlite3\u exec函数和静态回调函数来处理一些信息。我想将结果信息打印到名为sqlite3\u exec的类中定义的文件中。我说的是这样的 类生成调用{ 静态int回调(void*NotUsed,int argc,char**argv,char**azColName) { 对于(int x=0;x写文件(argc,argv); 返回0;//必须返回某些内容。 } int WriteToTheFile(int argc,char**argv) { 对于(int x=0

我使用SQLite的
sqlite3\u exec
函数和静态回调函数来处理一些信息。我想将结果信息打印到名为
sqlite3\u exec
的类中定义的文件中。我说的是这样的

类生成调用{
静态int回调(void*NotUsed,int argc,char**argv,char**azColName)
{
对于(int x=0;x文件在
sqlite3\u exec()调用中传递对象指针

sqlite3_exec(database, query, callback, (void*) this, &zErrMsg);
您将在回调的
NotUsed
参数中得到它:

static int CallBack(void *NotUsed, int argc, char **argv, char **azColName)
{
    MakingTheCall* obj = (MakingTheCall*) NotUsed;

    // whatever....
}

严格来说,
Callback()
函数应该是一个
extern“C”
自由函数,而不是一个静态成员。

通常,注册回调时,通过将指向中对象的指针作为闭包参数的一部分来实现。在
sqlite3\u exec
的情况下,API如下所示:

int sqlite3_exec(
  sqlite3*,                                  /* An open database */
  const char *sql,                           /* SQL to be evaluated */
  int (*callback)(void*,int,char**,char**),  /* Callback function */
  void *,                                    /* 1st argument to callback */
  char **errmsg                              /* Error msg written here */
);
因此,我将把指向对象的指针作为参数4传入。您的回调函数仍然是静态的,但它应该做的第一件事是将第一个参数转换为指向您感兴趣的对象类的指针。然后您可以调用所需的函数,该函数允许您写入特定于实例的
文件
您已通过。因此您的代码可能看起来有点像这样:

static int CallBack(void *closure, int argc, char **argv, char **azColName)
{
    MakingTheCall* obj = static_cast<MakingTheCall*>(closure);
    obj->WriteToTheFile(argc, argv);
    return 0; // Have to return something.
}

int WriteToTheFile(int argc, char **argv)
{
    for(int x = 0; x < argc; x++)
        File << argv[x];
    File<<"\n";
} 
静态int回调(void*closure、int argc、char**argv、char**azColName)
{
使球*obj=静态铸件(闭合);
obj->写文件(argc,argv);
返回0;//必须返回某些内容。
}
int WriteToTheFile(int argc,char**argv)
{
对于(int x=0;x文件如果使用
C++11
-支持进行编译,则可以使用匿名函数(lambda表达式)。 例如:

类生成调用
{
私人:
流文件;
无效调用(){
sqlite3_exec(数据库、查询、,
[&](void*NotUsed,int-argc,char**argv,char**azColName)->int
{
对于(int x=0;x文件重命名参数可能是个好主意,因为它现在已经被使用了。+1虽然我的版本中参数的名称是
NowUsed
Awesome,但我打算写同样的内容。我想知道如何使用void*。现在我觉得我需要更改问题的标题与实际答案没有任何关系你可能会提到
静态好友
方法,我非常好奇它在哪里起作用。有没有理由用
静态演员
代替常规的
(打电话*)(结束语)“< /代码> Case:@丹:主要是因为这是C++,而不是C。请检查Konrad Rudolphs对这个问题的回答:当lambda被作为函数指针铸造时,您不能使用捕获组。这就是为什么“第一参数回调”参数包含在代码> SqLeTe3ApEXECUTE()中。我尝试添加<代码> STD::函数< /C> >支持到SqLITE3,但是由于太多的代码>空隙*//>转换,以及在从C到C++的库中转换时的高度不耐烦,我失败了。
class MakingTheCall
{
private:
   ofstream File;
   void call(){
       sqlite3_exec(database, query,
           [&] (void *NotUsed, int argc, char **argv, char **azColName) -> int
           {
               for(int x = 0; x < argc; x++)
               File << argv[x];
               File<<"\n";
           },
           0, &zErrMsg);
   }
};