如果指定了参数,如何为函数指针分配地址?

时间:2012-05-31 10:10:33

标签: c++ function-pointers

在此之前,我使用了如此巨大的东西:

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 个答案:

答案 0 :(得分:4)

即使尝试解决编译错误,您也应该阅读编译器的诊断信息。我真的怀疑它曾经说过“没有。”

当您想要声明返回函数指针的函数(或函数指针)时,typedef特别有用。在一个简单的函数指针类型表达式中,它并不会给你带来太大的影响,因为你真的只需要在写一个括号时记住括号,如下所示:

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

对于C ++程序员来说,这两者都很容易阅读。

在你的情况下,typedef可能更好(因为你需要使用两次类型),但是当你 似乎无法理解可接受的隐式转换,我不会隐藏typedef幕后的问题。

在上面的示例中,您通常只更改事物的左侧。 C ++不允许将整数类型隐式转换为(任何)指针类型,并且以类似的方式,它不允许将对象指针类型隐式转换为函数指针类型。如果要将整数解释为函数指针,则需要强制转换 - 而不仅仅是任何转换,而是函数指针类型的reinterpret_cast

// 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("", ' ')

答案 1 :(得分:3)

使用typedef:

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

ShowPopupMessage = (funptr) your_address_goes_here;
ShowPopupMessage("hello", 0);

答案 2 :(得分:2)

这应该有效:

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

    funcPtr func = (funcPtr) 0x004837F0;

    func("asd", 0);
}

答案 3 :(得分:1)

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

int *ShowPopupMessage(const char *, char);

使用typedef创建一个函数指针:

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 ++值得一提的functors(和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());