2013-09-15 3 views
0

Я из Колумбии, поэтому ошибка на испанском языке. Это, кажется, самое быстрое место, чтобы получить ответ ...Ошибка конвертации нити C++

Я пытаюсь сделать простую программу, которая создает темы и сохраняет информацию в векторе, но когда я построить код появляется следующая ошибка:

...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); 

    } 

Я надеюсь, что вы люди могут помочь мне. Извините за плохой английский и спасибо за помощь

+4

Нестатические функции-члены не являются функциями. Вы не можете * вызывать * функцию-член (ей нужен объект!). Есть тысячи дубликатов этого вопроса. –

+1

И начинаем отсюда: http://stackoverflow.com/questions/1151582/pthread-function-from-a-class –

+1

Возможно, вы как-то измените свой язык на английский язык для GCC/Make run. – millimoose

ответ

1

На основании подписей, указанных в сообщении об ошибке, вы пытаетесь использовать функцию-член, где нужна функция или указатель void(): использование функции-члена напрямую не будет работать ! Вам нужно понять, что функция-член, по-видимому не принимающая никакого аргумента, действительно имеет скрытый аргумент: указатель this! Таким образом, объект должен быть предоставлен. Поскольку вы используете pthread_create(), нет никакого способа обойти это: вам нужно придумать нормальную функцию без аргументов. Поскольку функция, вероятно, должна быть объявлена ​​extern "C", вы также не можете использовать функцию-член static.

Что-то не кажется правильным, однако, как pthread_create() фактически принимает void*(*)(void*) в качестве аргумента, а не void*(*)(void), как утверждается, в сообщении об ошибке: void* может быть использован для передачи информации функции ввода потока, например, указатель на объект, который может быть восстановлен до нужного типа перед вызовом подходящей функции-члена.

0

Вы не можете использовать нестатические методы для потоковой передачи. Вам понадобится использовать следующий шаблон, чтобы получить способ проверки экземпляра многопоточным.

baseclass.h

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

baseclass.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); 
+0

'__stdcall' не является частью стандарта C++, а' extern 'C "(это, однако, означает, что функция не может быть членом 'static').Кроме того, правильный приведение, чтобы восстановить указатель на 'void *', полученный путем неявного преобразования в исходный тип указателя объекта, где он пришел из неявного преобразования, - 'static_cast (params)'. –

+0

@ DietmarKühl Интересно! Я всегда использовал 'reinterpret_cast' Спасибо за исправление. Вы правы в '__stdcall' Я думал, что он тоже может быть использован в GCC? – Serdalis

+0

Я предпочитаю стандартные возможности над расширениями компилятора, которые не будут работать при компиляции со следующим компилятором. Какой смысл быть заблокированным в конкретном компиляторе, если одна и та же логика может быть реализована в портативном переносном режиме без какой-либо или очень небольшой стоимости. –

Смежные вопросы