gpt4 book ai didi

c - C 中的函数数组

转载 作者:行者123 更新时间:2023-12-02 18:34:00 25 4
gpt4 key购买 nike

我正在开发一个项目,我必须为多个函数实现一个处理程序,所有这些函数都有一个与之关联的数字。它们所关联的数字就是不同函数的调用方式。知道这一点后,我希望能够使用数字作为函数的索引将它们分组到一个数组中。问题是,数组内部需要具有相同类型的元素,对吗?那么如何将这些函数放入数组中呢?

以下是函数的编号方式:

enum 
{
SYS_HALT, /* Halt the operating system. */
SYS_EXIT, /* Terminate this process. */
SYS_EXEC, /* Start another process. */
SYS_WAIT, /* Wait for a child process to die. */
SYS_CREATE, /* Create a file. */
SYS_REMOVE, /* Delete a file. */
SYS_OPEN, /* Open a file. */
SYS_FILESIZE, /* Obtain a file's size. */
SYS_READ, /* Read from a file. */
SYS_WRITE, /* Write to a file. */
SYS_SEEK, /* Change position in a file. */
SYS_TELL, /* Report current position in a file. */
SYS_CLOSE, /* Close a file. */
};

这是函数原型(prototype)列表:

void halt (void) NO_RETURN;
void exit (int status) NO_RETURN;
pid_t exec (const char *file);
int wait (pid_t);
bool create (const char *file, unsigned initial_size);
bool remove (const char *file);
int open (const char *file);
int filesize (int fd);
int read (int fd, void *buffer, unsigned length);
int write (int fd, const void *buffer, unsigned length);
void seek (int fd, unsigned position);
unsigned tell (int fd);
void close (int fd);

主要问题

是否有一种简单的方法可以将所有函数放入 C 中的数组或其他数据结构中?

任何帮助将不胜感激,这是一个学校项目,因此一个小示例或链接将非常有用,但我想自己创建解决方案。

谢谢

编辑:我希望能够做什么

我希望能够定义一些数组并在枚举序数的索引处存储指向函数的指针。

//I don't know how to handle the type here
<some_type> system_call_arr[128];

system_call_arr[SYS_HALT] = halt;
system_call_arr[SYS_EXIT] = exit;
system_call_arr[SYS_EXEC] = exec;

// and so on....

编辑2

既然 Ben 说所有参数都适合 32 位参数,我就不能定义这样的东西:

typedef int (*sys_func) (uint32_t, uint32_t, uint32_t);
sys_func syscall_array[128];

syscall_array[SYS_HALT] = (sys_func)halt;
//etc....

这样的做法是好的吗?

最佳答案

执行此操作的经典 UNIX 方法是为所有这些函数提供相同的签名(例如 int sys_func(struct args *a) ,然后将它们全部放入函数数组中。当您编码时您只需将调用的参数作为 arg1、arg2 等放入 struct args 中,并且每个系统调用都以不同的方式使用它们。或者您可以在其之上添加一个特殊结构的别名,以赋予它们有意义的名称。

在您的编辑中,您会问:“这样的做法是好的做法吗?”我在你的问题中给出了我的答案,这似乎是一个简单操作系统内核的实现。操作系统会以正常应用程序绝不会采用的方式进行欺骗。它可以使用有关字大小的假设(例如,所有内容都是 32 位,如 ILP-32 )并了解有关 ABI 的信息。因为实现这些事情是操作系统工作的一部分。如果您的操作系统可移植到其他平台,它将编译为不同的变体,例如syscall来处理这些情况。

为什么我建议struct args而不是你的方法?因为在操作系统中,在进行系统调用的用户和从函数指针表运行的实际代码之间会有几层。如果您在每一层显式传递这些参数,您将多次复制它们。如果第一层可以简单地提供一个指针,将参数“跳过”中间函数。如果您正在处理 ABI,其中调用约定是将参数插入堆栈,则可以避免完全复制参数,而只需采用适当的堆栈地址作为参数。

您可以在 McKusick 等人的4.4 BSD 操作系统的设计与实现中找到关于这一点以及操作系统设计的几乎所有其他方面的讨论。等人。如果您能找到旧的 4.3 版本,它实际上是一个相当薄的卷,并且仍然与您正在处理的内容完全相关。

关于c - C 中的函数数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8146627/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com