我正在构建一个用户定义的外壳。我有一个指向函数的指针数组——也就是说,一个包含可以在任何时候调用的共享库函数的数组。
我在这里输入定义
typedef void (*func_ptr)(char **);
func_ptr function;
void *pointers_to_functions[64];
我已经调试并确认我将指针放入数组的初始化工作正常,但这是安全措施的代码......
void initialize_built_in(){
void *handle;
char *error;
int i;
for (i = 0; i < 5; i++){
handle = dlopen(builtin_files[i], RTLD_LOCAL | RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
pointers_to_functions[i] = dlsym(handle, builtin_functions[i]);
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%c\n", *error);
exit(1);
}
if (dlclose(handle) < 0) {
fprintf(stderr, "%c\n", *dlerror());
exit(1);
}
}
}
这是发生段错误的地方——当我调用函数时
int execute_built_in(char **argv){
int i;
//scan through the builtin_functions strings to find the correct index of pointers_to_functions - that is, they have the same ordering
for (i = 0; i < sizeof(builtin_functions); i++){
if (!strcmp(argv[0], builtin_functions[i])){
//the index has been found
function = pointers_to_functions[i];
function(argv); //execute function
return 0;
}
}
return -1;
}
我的共享库确实将 argv 作为参数——所以我不认为这是问题所在。
正如我所说,调试我看到指针数组充满了地址。我想这可能是一个不正确的地址,但我在这里是一堵砖墙。
有任何想法吗?
所以我测试了指向函数调用的指针,在同一个文件中定义了我自己的函数类型(void *)。
func_ptr function;
void *testfunction(char **);
void *pointers_to_functions[64] = {testfunction};
该函数只是将某些内容打印到shell
然后我在execute_function函数中添加了一个条件来强制执行......
for (i = 0; i < sizeof(builtin_functions); i++){
if (i == 0){
function = pointers_to_functions[1];
char *bleh[] = {"bleh"};
function(bleh);
}
if (!strcmp(argv[0], builtin_functions[i])){
//the index has been found
function = pointers_to_functions[i];
function(argv); //execute function
return 0;
}
}
它有效WOOHOO!
所以我的动态链接有问题,我看不到。或者使用我的共享库——这不太可能,因为我已经构建了可以与同一项目的另一个 shell 代码一起使用的成功库。
那么,我的动态链接有什么问题?
这是一个示例共享库
#include <stdio.h>
#include <unistd.h>
struct NewBuiltIn{
char *CommandName[64];
char *FunctionName[64];
char *AnalyzerName[64];
};
struct NewBuiltIn pluggin_method = {{"cd", "cd", ""}};
void cd(char *argv[]) {
if(chdir(argv[1]) < 0){
printf("There was an error in changing your directory. Please check the path name and retry.\n");
}
}