Long story sort, I'm making a thread in c++ that starts a timer.
When a user starts playing the game, it starts the thread, and when user logs out - thread stops. - thus giving me the total time played.

Problem:
When using the code to start the thread -

hThreads[0] = CreateThread(NULL,0,Timer,(LPVOID)0,NULL,&id[0]);

it only works when I place this code into int main()

when I try and place the line where i need the thread to start - void start() - I get this error:

110 main.cpp [Warning] passing NULL used for non-pointer converting 5 of `void* CreateThread(_SECURITY_ATTRIBUTES*, DWORD, DWORD (*)(void*), void*, DWORD, DWORD*)'

Any ideas? Thanks alot

Dani AI

Generated

Two quick, practical points for : the compiler warning and the “works only in main()” symptom almost always come from a mismatch between what CreateThread (or your CRT thread entry) expects and what you actually passed. Common causes: the thread procedure has the wrong signature or calling convention, the proc is a non‑static member function, or a numeric parameter was passed as NULL (some compilers define NULL as (void*)0, which produces a conversion warning when passed to a DWORD argument).

Checklist to diagnose and fix

  • Verify the thread entry has a correct signature for the API you use (or make it a free/static function).
  • If the entry needs object state, pass this as the parameter and use a static wrapper that casts it back.
  • Replace pointer-style NULL with 0 (or an explicit cast) for non-pointer parameters to silence that warning.
  • Make sure the prototype is visible where you call the creation function and that you included the right headers.

A modern, simple pattern that avoids many Windows gotchas is to use std::thread and std::chrono for timing (no platform calling‑convention issues, easy capture of this, and portable time measurement):

std::atomic<bool> stop{false};
auto start = std::chrono::steady_clock::now();
std::thread t([&stop,start]{
    while(!stop.load()) std::this_thread::sleep_for(std::chrono::milliseconds(100));
    auto elapsed = std::chrono::steady_clock::now() - start;
    // store elapsed as needed
});
/* on logout */ stop = true; if (t.joinable()) t.join();

If you must use the Windows API and C runtime together, consider _beginthreadex instead of CreateThread, or keep your thread proc a static/free function and pass a pointer to your object. As pointed out, signaling (events or atomics) to request the thread stop is better than forcibly terminating it. Finally: for total play time, you often don’t need a continuous timer thread at all — record a start timestamp on login and compute elapsed on logout (high resolution via std::chrono or QueryPerformanceCounter).

Recommended Answers

All 2 Replies

Try using a thread like this, and events to halt the thread:

#include <windows.h>
#include <stdio.h>

DWORD WINAPI myfunk(LPVOID input)         // The actual Thread
{
    HANDLE VENTE = (HANDLE) input;    
    Sleep(1000);                          // Sleep for 1 sec
    SetEvent(VENTE);                      // Send a signal to main, asking it to go beyond the WaitForSingleObject
}

int main()
    {
    HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);  // Create a event as HANDLE 
    CreateThread(NULL, 0, myfunk, (LPVOID) event, 0, NULL);// Creat a thread and call it myfunk, pass the event to it
    
    printf("Waiting for the thread...\n");     // Screen output
    WaitForSingleObject( event, INFINITE );// Wait for "SetEvent(hEvent);"   
    
    system("PAUSE");                       // Pause
    return 0;                              // Exit
}

For your code, simply edit the event, and add a WaitForSingleObject to the thread, and let main pass a continue when needed.

About creating a thread inside a function then this works out:

/*----------------------------------------------------------------------------*/
/*--------------------------------HEADER--------------------------------------*/
/*----------------------------------------------------------------------------*/
#include <iostream>
#include <windows.h>

using namespace std;

/*----------------------------------------------------------------------------*/
/*--------------------------------THREAD1-------------------------------------*/
/*----------------------------------------------------------------------------*/
DWORD WINAPI Thread1(LPVOID lpParam)
{
while(1){cout << "1";}
}

/*----------------------------------------------------------------------------*/
/*--------------------------------THREAD2-------------------------------------*/
/*----------------------------------------------------------------------------*/
DWORD WINAPI Thread2(LPVOID lpParam)
{
while(1){cout << "2";}
}

/*----------------------------------------------------------------------------*/
/*-----------------------THREAD CREATION FUNCTION-----------------------------*/
/*----------------------------------------------------------------------------*/
void Thread()
    {
    CreateThread(NULL, 0, Thread1, NULL, 0, NULL);
    CreateThread(NULL, 0, Thread2, NULL, 0, NULL);
    }

/*----------------------------------------------------------------------------*/
/*-------------------------------MAIN PROGRAM---------------------------------*/
/*----------------------------------------------------------------------------*/
int main ()
    {
    Thread();
    system("PAUSE");
    return 0;
    }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.