您可以在char数组中表示函数吗?



我了解到功能和数据没有内在差异。您可以初始化一个字符的数组,并将炭指针施放为函数指针,然后将其用作函数。我没有足够的知识来实现它,因为我不知道编译器用来表示内存块内部功能指令的方式。但是我相信,该网站中有一些人有足够的专业知识来实现这一目标。:)

char* a = "blahbleeblue";//gibberish to other people
auto func = reinterpret_cast<void(*)()> a;
func();//due to careful planning, do what ever you ask

"我了解到功能和数据没有内在差异。"

在某些语言中,通常是解释的语言,就是这种情况。像JavaScript,Lisp等

在C中并非如此。数据和代码是完全不同的事情(我知道它们是存储在内存中的位,但并不相关),并且大多数操作系统都竭尽全力防止您做将它们混合在一起的事情(看起来像是错误或黑客入侵)。

进行CS500级课程时,您可能会找到代码随时重写的地方,有效地将其代码视为数据,但这很少见

也许这是一个X-y问题。
我假设您想根据某些字符串执行功能。

功能指针和地图
此技术仅在函数签名相同时才有效:

// Define a synonym for a function pointer that returns nothing  
// and has a single integer argument.
typedef void (*Function_Pointer(int argument));
// Some declarations:  
void Process_Apple(int a);
void Process_Pineapple(int b);
void Process_Carrot(int c);
// Initialize the map
typedef std::map<std::string, Function_Pointer> Function_Dictionary;
Function_Dictionary func_table;
func_table["apple"] = Process_Apple;
func_table["pineapple"] = Process_Pineapple;
func_table["carrot"] = Process_Carrot;
// You can use 'find' to find the associated function
Function_Dictionary::iterator iter;
std::string function_name = "apple";
iter = func_table.find(function_name);
if (iter != func_table.end())
{
  Function_Ptr f = iter->second;
  // Execute the function
  f(27);
}

表查找
您还可以创建一个表并使用查找。

struct Func_Assoc
{
  char * name;
  Function_Ptr f;
};
Func_Association lookup_table[] =
{
  {"apple", Process_Apple},
  {"pineapple", Process_Pineapple},
  //...
};
static const table_size =
  sizeof(lookup_table) / sizeof(lookup_table[0]);

搜索lookup_table查看名称,然后尊重关联的功能指针。该方案的一个很好的优势是,数据是恒定的,只读,并且可以通过您的程序访问,而无需任何运行时初始化。

另请参阅:工厂设计模式,反射

确实可以完成。这是一个示例:

#include <iostream>
#include <functional>
void say_hello(void) {
    std::cout << "Hello worldn";
}
using fptr = std::function<void(void)>; 
int main() {
    char *cptr = reinterpret_cast<char *>(&say_hello);
    fptr func = reinterpret_cast<void (*)(void)>(cptr);
    
    func();
    return 0;
}

输出:

Hello world

http://ideone.com/ufukcw


如果您想建立自己的字符串,这将以某种方式评估功能指针,这是不可能的,因为

  1. 指针必须指向用户定义的常数,即您决定使用的字符串。

  2. 这个常数必须活在某个内存地址,这与指针指向的内存地址相同...您可以看到问题吗?

现在,如果您还决定该指针必须以某种方式评估一个函数,那么不可能立即选择一个选择,因为

指针不能一次指向两种不同的事情。如果您的指针指向静态字符串(请参见上面的第二点),则不应在函数地址的同一时间点。您唯一需要的其他选择是其他两件事

  1. 您的编程非常低(内核几乎)
  2. 您确切知道数据段从哪里开始

从这里开始是高度理论的

在这一点上,我什至不确定这将有多好,因为我只看到OS代码遥远的东西。当操作系统启动时,它需要设置大量内存,以便初始化一些内容(确定可用的总内存,设置页面表,启动文件系统等)。该块分配具有已知的物理地址,并使用此块,引导过程的初始代码可以将功能放置在选择的位置。

现在,说您的功能居民在内存地址0x1EETC0DE,您可以使用普通的无符号整数保存此值。

unsigned secret_weapon = 0x1EETC0DE;

当时间合适时,您可以简单地创建此整数并将其价值投入到功能指针上,...您从这里决定。

最新更新