1

I've got this header:

class jmmvAsync
{
public:
    static void run(LPCTSTR msg);
};

and this .cpp

void jmmvAsync::run(LPCTSTR msg){
    MessageBox(NULL, msg, NULL, NULL);
}

And I'm calling a this function:

LPTCSTR file = "file";
thread t(jmmvAsync::run(file), 0);

thread function has this structure:

thread::thread(void (*aFunction)(void *), void * aArg)

Why am I getting wrong types when calling to "thread"?

Error code: COMPILE : error C2664: 'tthread::thread::thread(void (__cdecl *)(void *),void *)' : cannot make conversion of parameter 1 with type 'void' to 'void (__cdecl *)(void *)'

thread function expects paramater 1 to be void (__cdecl *)(void *) and my function is just void. I don't know how to make my function named run the same type as requested.

5
  • 2
    Have you tried (&jmmvAsync::run, file)? Commented Jul 14, 2015 at 11:28
  • 1
    Shouldn't you be passing the function, rather than the return value of the function? Commented Jul 14, 2015 at 11:29
  • @RefugnicEternium I got this error: '&' needs value L. And "file" is a parameter for run, not for thread. Commented Jul 14, 2015 at 11:37
  • @PaulRooney What do you mean? I'm trying to execute an async task using thread function, I need to pass a function to be executed asynchronous, that funcion is void! Commented Jul 14, 2015 at 11:39
  • @ProtectedVoid The function you pass to thread takes a void* parameter. The void* it receives when it is called is the second parameter. You're passing the result of calling the function. Commented Jul 14, 2015 at 11:46

1 Answer 1

1

As it was mentioned in comments (but maybe in an unclear fashion), your code tries to pass the return value of the function, instead of the pointer to the function.

This constructor

thread::thread(void (*aFunction)(void *), void * aArg)

expects a pointer to a function as the first argument.

This

jmmvAsync::run(file)

invokes the function and its result is the function's return value (which is void). This is absolutely not what you want. You want an address of the function:

&jmmvAsync::run

Send it to your constructor this way:

LPTCSTR file = "file";
thread t(&jmmvAsync::run, file);

Note: the second parameter is the file, not 0. This is a common pattern in C: you pass the address of the function and its parameter, which is of type void*, and the library code promises to call that function later, passing the parameter to it.

BTW as Aaron McDaid mentions, the type of jmmvAsync::run must be exactly what your constructor requests. That is, it must be declared to receive a parameter of type void* (not LPTCSTR), and be a static member function (which it is, judging by your code). Since you are using names like LPTCSTR, you probably only want your code to run on Windows, so you don't need to worry about the distinction between void* and LPTCSTR.

If in doubt, make a wrapper:

void wrapper_jmmvAsync_run(void* par)
{
    jmmvAsync::run(static_cast<LPTCSTR>(file));
}

...

LPTCSTR file = "file";
thread t(&wrapper_jmmvAsync_run, file);
Sign up to request clarification or add additional context in comments.

2 Comments

But the first argument should be of type void (__cdecl *)(void *). Does &jmmvAsync::run have that type? Will it need to be explicitly cast to that type? Or would it be better to write a separate thin wrapper that calls jmmvAsync::run on our behalf, and pass the wrapper to the thread instead?
Thanks, I understood now, Im a noob in C. It compiled successfully. Btw I'm getting a runtime error when executing it. I guess its because the used libs...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.