WINAPI: Создать новый поток в функции-члене класса - несовместимый тип параметра - PullRequest
0 голосов
/ 27 февраля 2019

Я реорганизовал довольно процедурный C ++ в нечто более классное.Исходный код работает просто отлично, и часть его запускает новый поток, чтобы выполнить некоторую очистку файла.Функция, выполняющая эту очистку, является точкой входа для нового потока.Смотрите код ниже.Примечание: этот код не будет выполняться, но он показывает принцип, который сработал.

#include <stdlib.h>

// Structure for passing application data to a new thread.
typedef struct threadData {
    networkShare*   netArchive;
    rig*            rigInfo;
    rigDatabase*    dbConn;
    networkConn*    netConn;
    char*           logBuffer;
} THREADDATA;

// Global handle to a mutex object
// Used to control access to the inter thread log buffer
HANDLE ghMutex;

DWORD WINAPI cleanLocalArchive(LPVOID lpParam) {
    THREADDATA* p_threadData = (THREADDATA*)lpParam;

    // ... Do stuff ...

    return <<something>>;
}

int main(int argc, char** argv) {
    // Variables for local archive thread
    HANDLE h_CleanerThread = 0;
    THREADDATA* p_threadData = NULL;
    DWORD dwThreadId;

    // Create a mutex with no initial owner
    ghMutex = CreateMutex(
        NULL,              // default security attributes
        FALSE,             // initially not owned
        NULL);             // unnamed mutex

    if (ghMutex == NULL) {
        printf("CreateMutex error: %d\n", GetLastError());
        return 1;
    }

    // Declare the data structure for passing app setting to a new Thread and populate it.
    p_threadData = DBG_NEW THREADDATA;
    p_threadData->netArchive    = &rigArchive;
    p_threadData->rigInfo       = &thisRig;
    p_threadData->logBuffer     = (char*)malloc(BUF_SIZE);
    p_threadData->dbConn        = &archiveDB;
    p_threadData->netConn       = &netConnection;

    // Initialise p_threadData->logBuffer in case we never put anything else in there.
    sprintf_s(p_threadData->logBuffer, BUF_SIZE, "");

    // Start a new thread
    h_CleanerThread = CreateThread(
        NULL,                   // default security attributes
        0,                      // use default stack size  
        cleanLocalArchive,      // thread function name
        p_threadData,           // argument to thread function 
        0,                      // use default creation flags 
        &dwThreadId);           // returns the thread identifier 


    // ... Do other stuff ...

    return 0;
}

Теперь я преобразовал код в классы, и функция "cleanLocalArchive" является функцией-членом класса приложения AircatFeeder.,Когда я вызываю эту функцию-член в CreateThread (), я получаю различные ошибки в зависимости от того, что я делаю с кодом:

Как есть: call line = "cleanLocalArchive,"

error C3867: 'AirCatFeeder::cleanLocalArchive': non-standard syntax; use '&' to create a pointer to member

Поэтому я добавляю амперсанд: call line = "& cleanLocalArchive,"

error C2276: '&': illegal operation on bound member function expression
error C2660: 'CreateThread': function does not take 5 arguments

После некоторого расчесывания головы и Google-Foo я нашел эту ссылку, которая, как я надеялся, решит проблему.Это, безусловно, пролило некоторый свет на причины.Я создал функцию-обертку вне класса и попытался вызвать ее.Функция и ее вызов были следующими:

Вызов функции:

// Start a new thread
    h_CleanerThread = CreateThread(
        NULL,                       // default security attributes
        0,                          // use default stack size  
        trampoline,         // thread function name
        p_threadData,               // argument to thread function 
        0,                          // use default creation flags 
        &dwThreadId);               // returns the thread identifier 

Функция оболочки:

DWORD trampoline(LPVOID data) {
    AirCatFeeder* scheduler = static_cast<AirCatFeeder*>(data);
    return scheduler->cleanLocalArchive(data);
}

Тем не менее, я все еще в конечном итоге с теми же проблемами / сообщениями об ошибках.Вызываю ли я функцию-член или функцию-обертку, IntelliSense по-прежнему выдает похожее сообщение об ошибке:

argument of type "DWORD(*)(LPVOID lpParam)" is incompatible with parameter of type "LPTHREAD_START_ROUTINE"

Надеюсь, теперь ясно, чего я пытаюсь достичь.Может кто-нибудь объяснить мне, что я делаю неправильно?Спасибо.

1 Ответ

0 голосов
/ 05 марта 2019

Ответ любезно предоставлен Гансом Пассантом.См. Комментарии к вопросу:

В батуте отсутствует определение WINAPI.

...