是否可以从 C 中的数组调用函数?
Is it possible to call functions from arrays in C?
当我制作我的终端时,我想知道我是否可以通过数组调用一个函数。
(此代码尚未完成,请代码有点乱。)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <unistd.h>
#include <limits.h>
#define true 1
#define false 0
typedef int bool;
/* Static */
static char Input[CHAR_MAX];
static char CurrentDirectory[CHAR_MAX];
static char *Command;
static char *Argument;
static char *Commands[]={"test","test2"};
/* Functions */
int Check_Command();
int test();
int test2();
/* --------- */
int main(){
printf("#######################\n\tterminal\n\tType \"help\" for the list of commands\n#######################\n");
prompt:
printf(">");
fgets(Input,CHAR_MAX,stdin);
int res=Check_Command();
if(res==0){printf("Unknown Command!\n");}
goto prompt;
}
/* Check_Command() function returns 0 if doesn't suceed and returns 1 of it suceeds */
int Check_Command(){
//Since input variable is static, no need to send in arguments
Input[strcspn(Input,"\r\n")]=0;
Command=strtok(Input," ");
Argument=strtok(NULL," ");
int x=0;
while(x<sizeof(Commands)){
if(strcmp(Command,Commands[x])==0){
Commands[x](); <----- Can I call a function like this?
return 1;
}
x++;
}
return 0;
}
/* Commands */
int test(){
printf("Success!\n");
getchar();
exit(0);
}
int test2(){
print("Success [2] \n");
getchar();
exit(0);
}
如果可能的话,这将被点亮,我懒得将命令变成可执行文件并为所有命令使用 if 语句。
如果你懒得阅读这里的整个代码是一个基本概念(未测试):
static *Commands[]={"test","test2"};
int main(){
char *Command="test";
int x=0;
while(x<sizeof(Commands)){
if(strcmp(Command,Commands)==0){
Commands[x]();
}
x++
}
}
int test(){
printf("Hi");
}
int test2(){
printf("hey");
}
编辑:
static char Commands[]={test,test2}; DOES NOT WORK
This also includes the "possible duplicate" answer. (Im using Mingw, Windows 10)
您似乎希望能够从用户那里接收一个字符串,例如 test2
,然后调用函数 test2()
。有两种主要方法可以解决此问题:
- 自制结构将名称映射到函数指针。
- 使用 'dynamic library loading' 和函数名称解析。
结构数组
首先,您定义一个结构,例如:
struct FuncName
{
const char *name;
int (*function)(void);
};
然后您可以定义一个数组:
struct FuncName functions[] =
{
{ "test", test },
{ "test2", test2 },
};
enum { NUM_FUNCTIONS = sizeof(functions) / sizeof(functions[0]) };
当你从用户那里得到一个名字时,你可以搜索名字数组并找到匹配的函数指针来调用。
int invoke_function(const char *name)
{
for (int i = 0; i < NUM_FUNCTIONS; i++)
{
if (strcmp(name, functions[i].name) == 0)
{
return (*functions[i].function)();
// Or just: return functions[i].function();
}
}
return -1; // No match found
}
这在所有系统上都能可靠地工作,但缺点是您必须在编译程序时创建 table 函数指针。
动态库
替代方法是在 Unix (POSIX) 系统上使用 <dlsym.h>
header 中的函数 dlopen()
and dlsym()
,或 Windows 上的等效函数。
通常,您希望在使用 dlopen()
加载的动态加载库中找到函数,但通常有一种方法可以在主执行程序 table 中搜索名称(传递一个空指针作为POSIX 系统上 dlopen()
的文件名)。然后可以调用dlsym()
获取指定名称对应的函数指针,调用即可。
void *dlh = dlopen(NULL, RTLD_NOW);
int (*funcptr)(void) = (int (*)(void))dlsym("test", dlh);
return (*funcptr)();
这省略了错误检查,您需要强制转换从 object 指针 (void *
) 转换为函数指针,因为 C 标准不要求这样做是可行的,但是 POSIX 确实(见规范
dlsym()
已经链接到)。
Non-uniform 函数签名
对于这两种解决方案,如果所有可调用函数都具有相同的接口,那么生活就很容易了。如果不同的函数有不同的接口,生活就会变得更加混乱(所以有些人不希望有参数,有些人希望有一个,有些人希望有两个,并且参数的类型因函数而异, return 类型也是如此)。期望使用大量强制转换并准备好让编译器提交 - 将代码与其他所有内容隔离开,以便将 non-portable 部分与主要代码分开。
注意:没有向编译器咨询任何此代码的有效性!
当我制作我的终端时,我想知道我是否可以通过数组调用一个函数。 (此代码尚未完成,请代码有点乱。)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <unistd.h>
#include <limits.h>
#define true 1
#define false 0
typedef int bool;
/* Static */
static char Input[CHAR_MAX];
static char CurrentDirectory[CHAR_MAX];
static char *Command;
static char *Argument;
static char *Commands[]={"test","test2"};
/* Functions */
int Check_Command();
int test();
int test2();
/* --------- */
int main(){
printf("#######################\n\tterminal\n\tType \"help\" for the list of commands\n#######################\n");
prompt:
printf(">");
fgets(Input,CHAR_MAX,stdin);
int res=Check_Command();
if(res==0){printf("Unknown Command!\n");}
goto prompt;
}
/* Check_Command() function returns 0 if doesn't suceed and returns 1 of it suceeds */
int Check_Command(){
//Since input variable is static, no need to send in arguments
Input[strcspn(Input,"\r\n")]=0;
Command=strtok(Input," ");
Argument=strtok(NULL," ");
int x=0;
while(x<sizeof(Commands)){
if(strcmp(Command,Commands[x])==0){
Commands[x](); <----- Can I call a function like this?
return 1;
}
x++;
}
return 0;
}
/* Commands */
int test(){
printf("Success!\n");
getchar();
exit(0);
}
int test2(){
print("Success [2] \n");
getchar();
exit(0);
}
如果可能的话,这将被点亮,我懒得将命令变成可执行文件并为所有命令使用 if 语句。 如果你懒得阅读这里的整个代码是一个基本概念(未测试):
static *Commands[]={"test","test2"};
int main(){
char *Command="test";
int x=0;
while(x<sizeof(Commands)){
if(strcmp(Command,Commands)==0){
Commands[x]();
}
x++
}
}
int test(){
printf("Hi");
}
int test2(){
printf("hey");
}
编辑:
static char Commands[]={test,test2}; DOES NOT WORK This also includes the "possible duplicate" answer. (Im using Mingw, Windows 10)
您似乎希望能够从用户那里接收一个字符串,例如 test2
,然后调用函数 test2()
。有两种主要方法可以解决此问题:
- 自制结构将名称映射到函数指针。
- 使用 'dynamic library loading' 和函数名称解析。
结构数组
首先,您定义一个结构,例如:
struct FuncName
{
const char *name;
int (*function)(void);
};
然后您可以定义一个数组:
struct FuncName functions[] =
{
{ "test", test },
{ "test2", test2 },
};
enum { NUM_FUNCTIONS = sizeof(functions) / sizeof(functions[0]) };
当你从用户那里得到一个名字时,你可以搜索名字数组并找到匹配的函数指针来调用。
int invoke_function(const char *name)
{
for (int i = 0; i < NUM_FUNCTIONS; i++)
{
if (strcmp(name, functions[i].name) == 0)
{
return (*functions[i].function)();
// Or just: return functions[i].function();
}
}
return -1; // No match found
}
这在所有系统上都能可靠地工作,但缺点是您必须在编译程序时创建 table 函数指针。
动态库
替代方法是在 Unix (POSIX) 系统上使用 <dlsym.h>
header 中的函数 dlopen()
and dlsym()
,或 Windows 上的等效函数。
通常,您希望在使用 dlopen()
加载的动态加载库中找到函数,但通常有一种方法可以在主执行程序 table 中搜索名称(传递一个空指针作为POSIX 系统上 dlopen()
的文件名)。然后可以调用dlsym()
获取指定名称对应的函数指针,调用即可。
void *dlh = dlopen(NULL, RTLD_NOW);
int (*funcptr)(void) = (int (*)(void))dlsym("test", dlh);
return (*funcptr)();
这省略了错误检查,您需要强制转换从 object 指针 (void *
) 转换为函数指针,因为 C 标准不要求这样做是可行的,但是 POSIX 确实(见规范
dlsym()
已经链接到)。
Non-uniform 函数签名
对于这两种解决方案,如果所有可调用函数都具有相同的接口,那么生活就很容易了。如果不同的函数有不同的接口,生活就会变得更加混乱(所以有些人不希望有参数,有些人希望有一个,有些人希望有两个,并且参数的类型因函数而异, return 类型也是如此)。期望使用大量强制转换并准备好让编译器提交 - 将代码与其他所有内容隔离开,以便将 non-portable 部分与主要代码分开。
注意:没有向编译器咨询任何此代码的有效性!