2

在那之前我用过这么大的东西:

int* ShowPopUpMessage = (int*)0x004837F0; //declare
((int (__cdecl*)(const char *, char))ShowPopUpMessage)("You see this message!", 0); //call

嗯,我认为没有必要说这有点令人困惑。

现在我想像这样声明普通函数指针:

int *ShowPopupMessage(const char *, char);

为了能够像这样调用该函数:

ShowPopupMessage("asd", 0);

但我无法为该指针分配函数地址。我试过:

int *ShowPopupMessage(const char *, char) = (int*)0x004837F0; //error: function "ShowPopupMessage" may not be initialized

//then this
int *ShowPopupMessage(const char *, char);
ShowPopupMessage = 0x004837F0; //nope

ShowPopupMessage = (int*)0x004837F0; //nope

*ShowPopupMessage = 0x004837F0; //nope

*ShowPopupMessage = (int*)0x004837F0; //nope

呃。还有其他方法吗?

4

4 回答 4

4

You really should read the compiler's diagnostics even with subsequent attempts of solving a compile error. I really doubt that it ever said "nope."

A typedef is especially useful when you want to declare a function (or a function pointer) returning a function pointer. In a simple function pointer type expression it doesn't buy you much, as you really only need to remember the parenthesis when you write one, like this:

int *ShowPopupMessage(const char*, char); // a function declaration
int (*ShowPopupMessage)(const char*, char); // a function pointer definition

Both are an easy read for C++ programmers.

In your case, a typedef might be preferable (as you need to use the type twice), but as you seem to have trouble understanding acceptable implicit conversions, I'm not going to hide the problem behind a typedef curtain.

In the examples above, you're mostly only changing the left-hand side of things. C++ does not allow implicit conversions of integer types to (any) pointer types, and in a similar fashion, it doesn't allow implicit conversions of object pointer types to function pointer types. If you want to interpret an integer as a function pointer, you need a cast -- and not just any cast, but a reinterpret_cast to a function pointer type.

// this is OK (with the cast), but ShowPopupMessage is not a function pointer,
// but a pointer to int
int *ShowPopupMessage = (int*)0xDEADBEEF;

// this is incorrect, as C++ does not allow implicit conversions from
// object pointers to function pointers
int (*ShowPopupMessage)(const char*, char) = (int*)0xDEADBEEF;

// this is OK (assuming you know what you're doing with 0xDEADBEEF)
int (*ShowPopupMessage)(const char*, char) =
        (int(*)(const char*, char))0xDEADBEEF;

// this is preferable in C++ (but it's not valid C)
int (*ShowPopupMessage)(const char*, char) =
        reinterpret_cast<int(*)(const char*, char)>(0xDEADBEEF);

// (this is a possibility in C++11)
#include <functional>
std::function<int(const char*, char)> ShowPopupMessage =
        reinterpret_cast<int(*)(const char*, char)>(0xDEADBEEF);
// it's used in much the same way as function pointers are
// i.e. you call it like you always call them: ShowPopupMessage("", ' ')
于 2012-05-31T11:52:36.963 回答
3

使用 typedef:

typedef int (*funptr)(const char *, char);
funptr ShowPopupMessage;

ShowPopupMessage = (funptr) your_address_goes_here;
ShowPopupMessage("hello", 0);
于 2012-05-31T10:15:42.727 回答
2

这应该有效:

{
    typedef int (*funcPtr)(const char *, char);

    funcPtr func = (funcPtr) 0x004837F0;

    func("asd", 0);
}
于 2012-05-31T10:15:16.310 回答
1

这是一个函数声明,而不是函数指针声明:

int *ShowPopupMessage(const char *, char);

使用 atypedef创建函数指针:

typedef int (*func_t)(const char*, char);

可以使用:

int _my_pop_up_one(const char* a_msg, char a_ch)
{
    std::cout << "one: " << a_msg << ", " << a_ch << "\n";
    return 0;
}

int _my_pop_up_two(const char* a_msg, char a_ch)
{
    std::cout << "two: " << a_msg << ", " << a_ch << "\n";
    return 0;
}

func_t show = _my_pop_up_one;
show("hello", 'a');
show = _my_pop_up_two;
show("hello", 'a');

因为这是 C++,所以值得一提的是函子的存在(而std::string不是char*),它允许一个对象像普通函数一样被调用:

struct func_t
{
    virtual int operator()(const std::string&, char) const = 0;
};

struct my_pop_up_one : func_t
{
    int operator()(const std::string& a_msg, char a_ch) const
    {
        std::cout << "one: " << a_msg << ", " << a_ch << "\n";
        return 0;
    }
};

struct my_pop_up_two : func_t
{
    int operator()(const std::string& a_msg, char a_ch) const
    {
        std::cout << "two: " << a_msg << ", " << a_ch << "\n";
        return 0;
    }
};

void display_pop_up(const func_t& a_func)
{
    a_func("hello", 'a');
}

display_pop_up(my_pop_up_one());
display_pop_up(my_pop_up_two());
于 2012-05-31T10:19:19.490 回答