是否可以使用强制转换为函数指针赋值字符串或字符串数组然后运行它?
我已经定义了一些函数int f1();
,int f2();
,依此类推
在main()
函数中,我读了一个字符串fct_name
并声明了一个指向函数int (*pv)();
的指针
我需要做这样的事情:
fct_name
可以包含值“f1”,“f2”等等。
pv = (some sort of cast)fct_name;
pv();
我的观点是我想避免使用条件指令来支持直接赋值(因为我的程序中有大量函数)
代码显然必须运行。
答案 0 :(得分:1)
Carey答案的变体,以防你使用* nix系统。 dlopen()
打开你的图书馆。 RTLD_LAZY
告诉加载器不要立即解决所有库的符号,并等待您尝试访问它们。 dlsym()
查找有问题的符号。
修改:更新了代码段以更好地符合您的说明:
#include <dlfcn.h>
int main(int argc, char *argv[])
{
void *handle = dlopen("libexample.so", RTLD_LAZY);
if (handle == NULL) {
// error
}
char fct_name[64];
// read input from terminal here
void *func = dlsym(handle, fct_name);
if (func != NULL) {
// call function here; need to cast as appropriate type
}
}
libexample.so将是一个包含您的函数的库,编译为共享库,如下所示:
gcc -Wall -o libexample.so example.c -shared -fPIC
话虽这么说,如果你要编译像这样的共享库的麻烦,你可能只想调用二进制文件中的函数。如果在编译时链接库,则可以这样做:
gcc -Wall -o test test.c -L. -lexample
-L.
告诉链接器在当前目录(.
)中查找库,-lexample
告诉它链接名为“libexample.so”的库。如果这样做,您可以直接在程序中调用库函数。
答案 1 :(得分:1)
假设您没有外部库并且正在尝试调用可执行文件中声明的函数,您可以自己进行查找
#define REGISTER_FUNC(name) {#name, name}
struct funclist
{
const char* name;
void (*fp)(void); //or some other signature
};
struct funclist AllFuncs[] = {
REGISTER_FUNC(f1),
REGISTER_FUNC(f2),
REGISTER_FUNC(f3),
{NULL,NULL} //LAST ITEM SENTINEL
};
现在,您可以在fct_name
中查找变量AllFuncs
。如果数字很小,您可以使用线性搜索,或者将它们全部插入到哈希表中以进行O(1)查找。
或者,如果您的姓名真的是f1
,f2
等,您可以这样做
void (*FuncList)(void)[] = {NULL, f1,f2,f3};
...
int idx = atol(fct_name+1);
if (idx && idx < MAX_FUNCS)
FuncList[idx]();
答案 2 :(得分:0)
您不能仅仅因为数组恰好包含函数名称而将char数组转换为函数。你需要做的是将你的函数放在DLL中,然后执行以下操作:
HMODULE dll = LoadLibrary("foo.dll");
pv func = (pv)GetProcAddress(module, fct_name);