type cast error DWORD to PVOID


Hey,

I'm having a problem passing the address of a function as an argument.
The function is defined as 'DWORD' and the argument takes (void*)

This problem was not existent when using the very same sourcecode on VS2010. But when I updated today to VS2013Community, this came up.

I tried alot of things including staticcast interpret etc.

So I call the function which looks like Add(void**, void*)
The second argument is causing the error.

The line which has the problem:

ApiHelper::GetInstance()->Add(&(PVOID&)function0, (PVOID)(&(PVOID&)myfunction_0));

Error 4 error C2440: 'type cast' : cannot convert from 'DWORD (__thiscall myfunction* )(char *,int)' to 'PVOID &' 2567 1

Hope I can get some help with this on how it should be.
Last edited on
Can you post the exact types.

What you're saying doesn't match the types to me. Are you sure Add() takes two functions?

This is the function:
void Add(void** srcFuncPtr, void* dstFuncPtr, const char* szDllName = NULL, const char* szFuncName = NULL);

And this is the myfunction_0:
DWORD myfunction_0(char* url, int size){}

The strange thing is this worked fine in VS2010professional
---


btw intellisense says about 'myfunction_0' in the Add() call:
1 IntelliSense: expression must be an lvalue 91
Last edited on
I am sorry, I don't have VS2013, so cannot test your example. This program compiles under gcc 5.3.0, clang 3.7.1 and VS2010 without warning.

Maybe you could use the casts I've used.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdint.h>
#include <stdio.h>

uint32_t srcFunc(void* )
{
        return 0;
}

uint32_t dstFunc(void* )
{
        return 0;
}

void Add(void** srcFuncPtr, void* dstFuncPtr, const char* szDllName = NULL, const char* szFuncName = NULL)
{
        printf("%p, %p, %p, %p\n", srcFuncPtr, dstFuncPtr, szDllName, szFuncName);
}

int main()
{
        Add((void**)srcFunc, (void*)dstFunc);
}
Last edited on

Hmm the code you provided indeed works, but that thing didn't fix my code. I however did find why it doesn't work.

DWORD dstFunc(char* url, int size)
{
return 0;
}
Even just keeping it DWORD works. But I need my code to be in a certain class and when I have it in this class, it fails.

Example:
1
2
3
4
5
6
7
8
class MyClass
{
public:
	DWORD dstFunc(char* url, int size)
	{
                return 0;
        }
};

When it is outside of the class, it works.

So I'm calling it as Add((void**srcFunc, (void*)MyClass::dstFunc);

MyClass:: is ruining it saying 'invalid type conversion' if it is in the class.


Last edited on
Yeah, I see.

A function exists somewhere, and that somewhere is it's address.

The type stuff, parameters and return type, allow the compiler to ensure that you're calling it correctly.

The value of a function is it's address. For example:
1
2
3
4
5
6
7
8
9
10
11
typedef int binary_calculation_t(int a, int b);
int sum(int a, int b)
{
    return a + b;
}

int main()
{
    binary_calculation_t f = sum;  // f is the address of sum()
    std::cout << "sum is " << f(2, 3) << std::endl; // call f
}


Now, that's true for member functions too, except when member functions are called, there's a hidden/extra parameter, the object's address. We call it "this" object. So it's not sufficient to get the member function's address, but you also need to pass in the object to operate on.

For your code above to work, it must have an instance of MyClass to use when it's about to use dstFunc. So there's probably more to this than you're showing.

This site explains a lot of the nuances with pointer to member functions.
https://isocpp.org/wiki/faq/pointers-to-members#fnptr-vs-memfnptr-types
Last edited on

Hmm then what could be so different between VS2010 and VS2013 that it worked before?

I'm performing a Hook and the typedef of the function which is to be replaced indeed does have a (this, arg1, arg2) structure. For my own function it was not needed.

Even If I create an instance of it, it says 'invalid type conversion' in the third line below

1
2
3
MyClass* mc = new MyClass();
typedef DWORD(__thiscall * Type_exmp)(char* url, int size);
Type_exmp adr = (Type_exmp)mc->dstFunc;

Last edited on
Yeah, that's an error. The correct definition of Type_exm is:
 
typedef DWORD(MyClass::* Type_exmp)(char* url, int size);


Ok, we're almost back to where we started. You're saying VS2010 and below accept the cast and the newer versions don't. I get that.

What I don't get, is how you're using that function pointer. I see the Add() function, but no context. This example came from that like I posted previously.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Fred
{
public:
    void memberFn();
    static void staticMemberFn();  // A static member function can usually handle it
};

// Wrapper function uses a global to remember the object:
Fred* object_which_will_handle_signal;
void Fred_memberFn_wrapper()
{
    object_which_will_handle_signal->memberFn();
}

int main()
{
    signal(SIGINT, Fred::memberFn);   // Can NOT do this
    signal(SIGINT, Fred_memberFn_wrapper);  // Okay
    signal(SIGINT, Fred::staticMemberFn);   // Okay usually; see below
}


To use that member function pointer, you need an object to bounce off. In the example, it's global. For your code to work, despite the differences of opinion of that cast, you must have such an object to bounce off. I can't see that in from what you've posted. I'd like to see it, to provide a suitable hack around the problem.
Last edited on
Thaks alot kbw for the help and input.

It seems like it works now by using the correct typedef as you gave it.
Topic archived. No new replies allowed.