【问题标题】:Passing an Object and getting the return value from a thread call传递对象并从线程调用中获取返回值
【发布时间】:2013-10-09 11:57:13
【问题描述】:

我想通过线程调用将一个类对象传递给其他类的方法,我试过但得到错误任何人可以帮助我解决这个问题。

struct sample{

  int status;

  std::vector <std::string> a_row;

  size_t column_count;

  std::vector <std::string> column;

};

class sess {

public:

    int a;

    sess(int);

    sess();

};

class Gen { 

     private: 

       static Gen* gen_obj;

     public:

       static bool Gen_InstanceFlag;

       static Gen* GetInstance();

       sample addition(sess);

};

/* 头文件结束 */

/* cpp 文件的开头 */

include"Class_thread_mixing.h"

bool Gen::Gen_InstanceFlag=false;

Gen* Gen::GetInstance(){

if(!Gen::Gen_InstanceFlag){

    Gen::gen_obj = new Gen();

   Gen::Gen_InstanceFlag= true;

   return gen_obj;

  }
else {

    return gen_obj;

  }

}


sample addition(sess ses_obj){

 sample sam;

 sam.a_row.push_back("success");

 sam.column.push_back("result");

 sam.column_count=1;

 sam.status=ses_obj.a;

return sam;
}


int main(int argc, char* argv[])

{

  HANDLE myhandleA;

  Gen* gen=Gen::GetInstance();

  sess ses_obj(10);

  myhandleA=(HANDLE)_beginthreadex(0, 0, gen->addition(ses_obj),(void*)0, 0, 0);

  WaitForSingleObject(myhandleA, INFINITE);

  CloseHandle(myhandleA);

  getchar();

  return 0;

}

这是我的代码,我收到类似“错误 C2665: '_beginthreadex' : 2 个重载都不能转换所有参数类型”的错误

谁能建议我谁可以将 sess 的对象传递给线程调用中的函数,以及如何从线程中获取结果。

感谢您的回答..

有任何选项可以让我直接在线程中调用函数而不调用独立的线程函数,就像我在代码中提到的 [(HANDLE)_beginthreadex(0, 0, gen->addition(ses_obj),(无效*)0, 0, 0)]

我需要在线程中调用添加方法,任何人都可以帮助我。

【问题讨论】:

  • 发布有关编译错误的问题时,请在问题中填写完整、完整且未经编辑的错误消息。这将使帮助您变得更加容易。您可能想阅读the Stack Overflow question checklist,它将帮助您写出好问题。

标签: c++ multithreading beginthreadex


【解决方案1】:

这里的问题是,您实际上不是将函数传递给_beginthreadex 调用的函数,而是调用带有参数的函数,导致_beginthreadex 函数被调用并返回来自Gen::addition 的值。这个结构当然不是一个函数,所以编译器会抱怨。

虽然解决这个问题并不简单。首先是因为独立函数(_beginthreadex 所要求的)与类成员函数不同。原因是所有类成员函数实际上都有一个“zeroeth”隐藏参数,这是类成为可在成员函数内部使用的this 指针。

最好的解决方案可能是创建一个独立的函数,它接受一个指向结构的指针作为参数,该结构包含对象实例,以及实际成员函数的参数。

类似这样的:

struct call_data
{
    sess sess_obj;
    Gen* gen_obj;
};

static void thread_function(void* data)
{
    call_data *call = reinterpret_cast<call_data*>(data);

    // Do the actual member function call
    call->gen_obj->addition(call->sess_obj);
}

int main()
{
    ...

    call_data call = { ses_obj, gen };
    myhandleA=(HANDLE)_beginthreadex(0, 0, thread_function, &call, 0, 0);

    ...
}

【讨论】:

  • 嗨,有没有什么选项可以让我直接在线程中调用函数而不调用独立的线程函数。就像我在代码中提到的 [(HANDLE)_beginthreadex(0, 0, gen- >addition(ses_obj),(void*)0, 0, 0) ]
  • @vamsikrishna 不,没有。首先,您现在要做的是调用 _beginthreadex 调用中的成员函数。其次,因为成员函数与函数不同。我在回答中解释了所有这些。
【解决方案2】:

线程的入口点不能是类方法。它必须是静态的或在全局范围内。

你需要像这样定义一个静态方法

static unsigned ThreadEntry(void* arg)
{
   sess *p = (sess*)arg;
   Gen::GetInstance()->addition(*p);
} 

然后像这样运行线程:

sess ses_obj(10);
myhandleA=(HANDLE)_beginthreadex(0, 0, ThreadEntry,(void*)&ses_obj, 0, 0);

【讨论】:

  • 嗨,有没有什么选项可以让我直接在线程中调用函数而不调用独立的线程函数。就像我在代码中提到的 [(HANDLE)_beginthreadex(0, 0, gen- >addition(ses_obj),(void*)0, 0, 0) ]
  • 没有。但是您可以从类中调用静态函数。意味着 ThreadEntry 可以是 "static unsigned Gen::ThreadEntry(void* arg){...}" 但它仍然是一样的。
  • 非常感谢..:)
猜你喜欢
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多