【问题标题】:C++ thread conversion error [duplicate]C ++线程转换错误[重复]
【发布时间】:2013-09-15 22:32:46
【问题描述】:

我来自哥伦比亚,所以错误是西班牙语。这似乎是获得答案最快的地方...

我一直在尝试制作一个简单的程序来创建线程并将信息保存在向量中,但是当我构建代码时出现下一个错误:

...Lanzador.cpp|19|error: no se puede convertir ‘void* (Hilo::*)(void*)’ a ‘void* (*)(void*)’ para el argumento ‘3’ para ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’|

我有三个文件:Hilos 的标题:

    #ifndef HILO_H
    #define HILO_H
    using namespace std;

    class Hilo
    {
        public:
            Hilo();
            virtual ~Hilo();
            void addHilo(int);
            void* ImprimirHilo(void*);

        protected:
        private:
        };

    #endif // HILO_H

Hilo.cpp 说:

    #include <iostream>
    #include <vector>
    #include <cstdlib>
    #include <pthread.h>
    #include <unistd.h>
    #include "Hilo.h"
    using namespace std;
    vector<int> info (1);
    Hilo::Hilo()
    {
    //ctor
    }

    Hilo::~Hilo()
    {
     //dtor
    }

    void Hilo::addHilo(int tiempo){

         info.push_back(tiempo);

    }


    void* Hilo::ImprimirHilo(void *threadid)
    {
         long tid;
         tid = (long) threadid;
        int n =info.at(tid);
        for (int i=n; i>0; i-- ){
        info.at(tid)=i;
        cout << "El hilo numero: " << tid << " tiene " << i <<" segundos"<< endl;
        sleep(1);
        }
        pthread_exit(NULL);
      }

以及拥有主要 Lanzador.cpp 的类

    #include <iostream>
    #include <cstdlib>
    #include <pthread.h>
    #include "Hilo.h"
    using namespace std;
    int main (){
        Hilo h;
        pthread_t threads;
        int tiempo=0;
        int rc;
        int contador=0;
        cout << "Para salir oprima 0 \n"<<endl;
        cout << "Escriba el tiempo del hilo" << endl;
        while (true){
            cin >> tiempo;
            if (tiempo>0){
                contador++;
                h.addHilo(tiempo);
                rc = pthread_create(&threads, NULL,&h.ImprimirHilo, (void*)contador);
                if (rc){
                     cout << "Error:unable to create thread," << rc << endl;
                     exit(-1);
                }
           }
      }


      pthread_exit(NULL);

   }

我希望你们能帮助我。抱歉英语不好,感谢您的帮助

【问题讨论】:

  • 非静态成员函数不是函数。你不能调用一个成员函数(它需要一个对象!)。这个问题有数千个重复项。
  • 您可以将您的语言环境更改为 GCC 的英语 / 以某种方式运行。
  • @millimoose,是的,只需设置 LANG=C
  • 横向建议:新的&lt;thread&gt; 不会比尝试结合pthreads 和C++ 更好吗?或者 Boost.Thread 如果&lt;thread&gt; 不可用。 (也就是说,我承认我对这些库的了解就是它们存在。)

标签: c++ multithreading pthreads


【解决方案1】:

根据错误消息中提到的签名,您正在尝试使用需要void() 函数或其指针的成员函数:直接使用成员函数将不起作用!你需要意识到一个表面上不带参数的成员函数实际上有一个隐藏的参数:this 指针!因此,需要提供一个对象。由于您使用pthread_create(),因此没有任何办法:您需要提出一个不带参数的普通函数。由于该函数可能需要声明为extern "C",因此您也不能使用static 成员函数。

但是,有些事情似乎不对,因为 pthread_create() 实际上将 void*(*)(void*) 作为参数,而不是错误消息中声称的 void*(*)(void)void* 可用于将信息传递给线程入口函数,例如,指向可以在调用合适的成员函数之前恢复为正确类型的对象的指针。

【讨论】:

    【解决方案2】:

    您不能在线程中使用非静态方法。 您必须使用以下模式来获得实例感知方法的多线程。

    基类.h

    class baseclass
    {
        int a;
        static void __stdcall threaded(void* params);
    }
    

    基类.cpp

    void __stdcall 
    threaded(void* params)
    {
        // this is your class instance
        pThis = static_cast<baseclass*>(params);
        printf("%d", pThis->a);
    }
    

    main.cpp

    // class instance is entered as the parameter
    rc = pthread_create(&threads, NULL, Hilo::ImprimirHilo, (void*)&h);
    

    【讨论】:

    • __stdcall 不是 C++ 标准的一部分,而 extern "C" 是(但是,这意味着该函数不能是 static 成员)。此外,将通过隐式转换获得的指向void* 的指针恢复为通过隐式转换获得的指向原始对象指针类型的正确转换是static_cast&lt;baseclass*&gt;(params)
    • @DietmarKühl 有趣!我一直用reinterpret_cast 谢谢指正。您对__stdcall 的看法是正确的,不过我认为它也可以在 GCC 中使用?
    • 我更喜欢标准工具而不是编译器扩展,后者在使用下一个编译器编译时不起作用。如果相同的逻辑可以以可移植的可移植方式实现而无需或花费很少的成本,那么锁定在特定编译器中的意义何在?
    • @DietmarKühl 我只在 MSVC / GCC 环境中工作过。如果扩展在两者中都可用,使代码更具可读性并使我的生活更轻松,那么不使用它是有害的。我理解您的观点,但使用 extern "C" 来执行此操作对我来说似乎有点 hacky。主要是风格/便携性的问题。
    猜你喜欢
    • 2012-09-25
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 2018-05-04
    • 2014-08-07
    • 2012-09-07
    • 2020-09-19
    • 2011-08-22
    相关资源
    最近更新 更多