2

I am trying to pass parameters to a function pointer being passed as a parameter.

Code:

void Test(wchar_t* a, wchar_t* b)
{
    // ...
}

void Test2(void(*Func)(wchar_t*, wchar_t*))
{
    // ...
}

int main()
{
    Test2(Test(L"Hello", L"Testing"));
    return 0;
}

I am getting this error:

argument of type "void" is incompatible with parameter of type "void (*)(wchar_t *, wchar_t *)"

How do I fix this to accomplish what I'm trying to achieve?

Edit: Sorry for not being clear. What I'm actually trying to accomplish is inject a function into a child process and pass two parameters (wchar_t*, wchar_t*) so I can use them. But the main function can either be void or int argc, char** argv. So I accomplished what I'm trying to achieve by simply using global variables

3
  • A lambda might suffice depending on what you want to do. Commented Jul 5, 2016 at 21:25
  • 2
    What exactly is it that you're trying to achieve? Your code is, as you've noticed, not valid C so it's not a useful demonstration of your intent. Commented Jul 5, 2016 at 21:27
  • πάντα ῥεῖ's answer is what I'm trying to achieve but I want a different way to do it like in C++ with templates Commented Jul 5, 2016 at 21:32

3 Answers 3

7

You probably want to have something like

void Test2(void(*Func)(wchar_t*, wchar_t*),wchar_t* x, wchar_t* y)
{
    (*Func)(x,y);
}

int main()
{
    Test2(Test,L"Hello", L"Testing");
    return 0;
}

instead.


As for your comment

How do i do this in C++ with templates?

I could think of

template<typename Param>
void Test2(void(*Func)(Param, Param), Param x, Param y) {
    (*Func)(x,y);
}

void Test(wchar_t* a, wchar_t* b);

int main() {
    Test2(Test,L"Hello", L"Testing");
    return 0;
}

This should just work fine.

Sign up to request clarification or add additional context in comments.

12 Comments

your answer is what I'm trying to achieve. How do i do this in C++ with templates?
@user1304765 Updated my answer. Still not sure what you actually want.
Yea its actually a bit more complicated. I have one function that injects code (a function) into a child process so it has this parameter: int(Main)(wchar_t, wchar_t*). The Main function that I'm passing to it calls a function that takes two wchar_t*.
@user1304765 Well, I don't see so much need for a template function then. I hope your child process is a thread actually though. You cannot change the signature of main() and pass arbitrary parameter types.
@user1304765 Calling main inside your program is not a good idea. In fact it's forbidden by the standard (See section 3.6.1). If this is a mis-communication, groovy, but if not I recommend a re-think.
|
0

There are more than one way to fix tihs issue, however, let me just try to show why this error is occuring.

Every function has a type of value associated with it. This means, that every function evaluates to a value of some type. This is indicated by its return value.

For example:

int foo(/*whatever*/); 

evaluates to an int. So foo(/*whatever*/) can be used anywhere an int is expected. For example like int a = b + foo(/*whatever*/).

Simlarly float bar(/*whatever*/); evaluates to a float, hence bar(/*whatever*/) can be used anywhere a float is expected. For example like float a = b + bar(/*whatever*/).

A function that returns void like void foobar(/*whatever*/) however, evaluates to void and cannot be used where a value of some type (say int, float, etc) is expected.

Now coming to code. This line in your main function has the issue:

int main()
{
    Test2(Test(L"Hello", L"Testing")); /* Issue here */
    return 0;
} 

Here you are passing Test(L"Hello", L"Testing") as the argument to Test2. Now remember, that Test(/*whatever*/), evaluates to a void because Test returns a void.

So what you are doing in that line is something like

Test2(/*something that evaluates to a void*/);

However, Test2 expectes a void (*)(wchar_t*, wchar_t*), which is a pointer to a function that returns void, which is different from void.

So what is happening, is that the compiler is seeing that you are passing a void in a place where a void (*) (wchar_t*, wchar_t*) is expected, so it is correctly indicating that error.

There can be different ways to solve this issue which are mentioned in other answers.

Comments

0

Do I need to use C++ templates?

Of course, you can do that using C++ templates as it follows:

#include<utility>

// ...

template<typename F, typename... A>
void Test2(F &&f, A&&... a)
{
    std::forward<F>(f)(std::forward<A>(a)...);
    // ...
}

// ...

Test2(Test, L"Hello", L"Testing");

But you don't need them to do what you are trying to do.
@πάνταῥεῖ has already explained why in its answer.

Comments

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.