【问题标题】:How to assign functions to a function pointer?如何将函数分配给函数指针?
【发布时间】:2019-03-22 20:02:47
【问题描述】:

我正在编写一个 Gameboy 模拟器,对于 CPU 的指令,我在此处(在 cpp.hpp 中)使用此结构来存储有关它们的信息。该地图用于通过与其个人操作码相同的密钥访问所有这些信息:

    struct instruction {
        std::string name;    //name of the instruction
        int cycles;          //clock cycles required to be executed
        int paramNum;        //number of params accepted
        void* function;      //code to be executed
    };
    class Cpu {
        private:
            std::map<unsigned char, instruction> instrMap;
            void Cpu::fillInstructions(void);
            instruction addInstruction(std::string, int, int, void*);
        public:
            void add_A_n(unsigned char);
    }

然后在 cpu.cpp 中,我有一个函数,例如我想转换为函数指针以便分配给 struct 指令的字段。所以我有这个代码:

    void Cpu::add_A_n(unsigned char n) {
        //body     
    }
    void Cpu::addInstructions(std::string name, int cycles, int paramNum, void* function) {
        instruction i = {name, cycles, paramNum, function};
        return i;
    }
    void Cpu::fillInstructions() {
        instrMap[0x80] = Cpu::addInstruction("ADD A, n", 4, 0, (void*)&Cpu::add_A_n);
    }

目标是从内存中获取操作码,然后使用此操作码从映射中检索有关相关指令的信息,最后通过使用 switch case 选择正确的指令来执行其功能:

    ((void (*)(void))instrMap[0x80].function)(); //for 0 params
    ((void (*)(unsigned char))instrMap[0x90].function)((unsigned char)operand); //for 1 param

我的目标是将所有函数,甚至是需要一些参数的函数,转换为结构中的函数。

正确执行了相应的功能,但引发了警告:

警告:从 'void (Cpu::)()' 转换为 'void' [-Wpmf-conversions] instrMap[0x80] = Cpu::addInstruction("ADD A, n", 4, 0, (void*)&Cpu::add_A_n);

我该如何解决?为什么会这样?谢谢

【问题讨论】:

  • 我认为这不是实现 CPU 仿真器的最佳方式,因为通过将函数指针传递为 void* 会失去类型安全性。您是否考虑过使用结构将传递给virtual 函数的参数存储在代表指令的子类中?
  • 不请自来的建议:使用std::unordered_map,除非您需要在地图中订购,而您可能不需要。 (标准中还有一个平面地图待定,Google 的flat_hash_map 暂时。)
  • @metal 它确实需要 C++11,但我可能需要使用它。
  • 您还可以从派生 std 版本的boost::unordered_map 获取与 C++98 兼容的哈希映射。

标签: c++ c++11


【解决方案1】:

&amp;Cpu::add_A_n返回一个pointer to a member function,和普通的函数指针有很大区别,两者不能混用。指向成员函数的指针的奇怪之处在于,非静态成员函数都需要this 实例才能调用该函数。

在您的情况下,如果像 add_A_n 这样的函数确实不依赖于 this,则只需将其设为 static 或非成员函数:

class Cpu {
    ...
    static add_A_n(unsigned char);
};

这样,它就不再需要调用this&amp;Cpu::add_A_n变成了一个普通的函数指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 1970-01-01
    相关资源
    最近更新 更多