none
При присваивании имени функции-рабочего колбэка в переменную PTP_WORK_CALLBACK возникает ошибка. RRS feed

  • Вопрос

  • Извините, у меня происходит ошибка при присваивании переменной типа PTP_WORK_CALLBACK имени функции, являющейся рабочим колбэком. Функция-рабочий колбэк определена так:

    VOID CALLBACK WordCount::CountWordsInFiles(PTP_CALLBACK_INSTANCE p_Instance, PVOID p_WordCountContext, PTP_WORK p_Work)
    {
    	EnterCriticalSection(&CriticalSection);
    	UNREFERENCED_PARAMETER(p_Instance);
    	UNREFERENCED_PARAMETER(p_Work);
    
    	// Получить имена текстовых файлов, в которых требуется выполнить подсчёт слов
    	// м путь к папке, содержащий эти файлы.
    	struct WordCountContext& wordCountContext = *((WordCountContext*)p_WordCountContext);
    	vector<basic_string<char>>& textFilesNames = wordCountContext.textFilesNames;
    	basic_string<char> folderPath = wordCountContext.p_FolderPath;
    
    	// Счётчик слов в файле.
    	unsigned wordsInFile;
    
    	// Сделать указанную папку текущей.
    	::SetCurrentDirectory(folderPath.c_str());
    	// Определить итератор для вектора имён файлов.
    	vector<basic_string<char>>::const_iterator fileNames_Iter;
    	// Установить этот итератор на начало вектора.
    	fileNames_Iter = textFilesNames.begin();
    	// Для каждого файла, имя которого получено из вектора, выполнить следующее:
    	for (; fileNames_Iter != textFilesNames.end(); fileNames_Iter++)
    	{
    		// Создать поток для чтения из файла.
    		ifstream fileStream(*fileNames_Iter);
    		// Проверить, открылся ли файл.
    		if (fileStream.is_open())
    		{
    			wordsInFile = 0;
    			// Выполнять чтение.
    			while (fileStream.good())
    			{
    				string word;
    				// Сохранить очередное прочитанное слово в буфере.
    				fileStream >> word;
    				// Подсчитать количество слов в текущем файле.
    				wordsInFile++;
    				// Подсчитать общее количество слов во всех файлах.
    				WordCount::wordsInFilesTotally++;
    			}
    
    			// Вывести слообщение о количестве слов в текущем файле.
    		        cout << endl << "В файле " << *fileNames_Iter << " количество слов равно " << wordsInFile << endl;
    		}
    	}
    	LeaveCriticalSection(&CriticalSection);
    		return;
    }

    В той функции, в которой я создаю пул потоков, я в частности пишу:

    PTP_WORK_CALLBACK workcallback = CountWordsInFiles;

    И сразу же в design-time возникает ошибка следующего содержания:

    IntelliSense: значение типа "void (__stdcall WordCountFunc::WordCount::*)(PTP_CALLBACK_INSTANCE p_Instance, PVOID p_WordCountContext, PTP_WORK p_Work)" нельзя использовать для инициализации сущности типа "PTP_WORK_CALLBACK"
    Из-за чего появляется эта ошибка? Вроде всё делаю правильно.


    • Изменено Purple_Apple 16 декабря 2014 г. 14:41
    16 декабря 2014 г. 14:40

Ответы

  • Нестатический метод класса по сигнатуре не подходит для обратного вызова - у него дополнительные скрытый параметр есть (this). Если хотите использовать этот метод - сделайте его статическим. Тип метода, в котором выполняется присваивание, роли не играет.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!


    • Помечено в качестве ответа Purple_Apple 16 декабря 2014 г. 19:30
    • Изменено kosuke904 16 декабря 2014 г. 20:19
    16 декабря 2014 г. 16:14

Все ответы

  • Ребята, помогите, пожалуйста. Я уже у себя практически всё перепробовал - ошибка остаётся. А в http://msdn.microsoft.com/en-us/library/windows/desktop/ms686980(v=vs.85).aspx сделано именно так. Правда у меня эти функции - члены класса. Колбэк - private (закрытый член), а та в которой эта ошибка - public (открытый член).

    То что WordCount::CountWordsInFiles (колбэк) - не статическая, а та в которой делается присваивание  (PTP_WORK_CALLBACK workcallback = CountWordsInFiles;) является статической - это не играет роли. Я объявлял нестатической ту функцию, в которой выполняется указанное присваивание, и всё равно - в результате та же ошибка.


    • Изменено Purple_Apple 16 декабря 2014 г. 15:41
    16 декабря 2014 г. 15:27
  • Нестатический метод класса по сигнатуре не подходит для обратного вызова - у него дополнительные скрытый параметр есть (this). Если хотите использовать этот метод - сделайте его статическим. Тип метода, в котором выполняется присваивание, роли не играет.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!


    • Помечено в качестве ответа Purple_Apple 16 декабря 2014 г. 19:30
    • Изменено kosuke904 16 декабря 2014 г. 20:19
    16 декабря 2014 г. 16:14
  • Спасибо. То есть метод должен обязательно быть статическим? А можно заключать тело статического метода в конструкцию

    EnterCriticalSection(&CriticalSection); . . . . . . . .

    // Здесь тело метода

    . . . . . . . . LeaveCriticalSection(&CriticalSection);

    или нет. Если нет, то как тогда делать синхронизацию между потоками?

    16 декабря 2014 г. 16:49
  • Почему бы нет? Статический метод - такой же кусок кода. Что именно Вас смущает? :)

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    16 декабря 2014 г. 17:27
  • Спасибо за помощь.
    16 декабря 2014 г. 19:31