我正在尝试进行 FFI 调用,但在 ffi_call(本例中为 gtk_init
)调用的函数内出现段错误。我不知道我哪里搞砸了。
/*
* gtk_init.cc
*/
#include <ffi.h>
#include <gtk/gtk.h>
void test();
int main(int argc, char *argv[]) {
test();
return 0;
}
void test() {
ffi_cif cif;
ffi_type *arg_types[2];
void *arg_values[2];
ffi_status status;
ffi_arg result;
arg_types[0] = &ffi_type_uint;
arg_types[1] = &ffi_type_pointer;
status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_void, arg_types);
if (status != FFI_OK) {
printf("Failed to prep_ffi\n");
return;
}
int argc = 4;
char **argv = (char**)malloc(sizeof(char*) * argc);
argv[0] = strcpy((char*)malloc(sizeof(char) * 6), "test");
argv[1] = strcpy((char*)malloc(sizeof(char) * 13), "--gtk-debug");
argv[2] = strcpy((char*)malloc(sizeof(char) * 6), "misc");
argv[3] = strcpy((char*)malloc(sizeof(char) * 6), "last");
arg_values[0] = &argc;
arg_values[1] = &argv;
ffi_call(&cif, FFI_FN(gtk_init), &result, arg_values);
// gtk_init(&argc, &argv);
for (int i = 0; i < argc; i++) {
printf("%s\n", argv[i]);
free(argv[i]);
}
free(argv);
}
完整的要点可以是found here .
最佳答案
问题是 ffi_call()
取参数的地址为 gtk_init()
取 int *
和 char ***
您需要获取它们的地址,以便给出 int **
和 char ** **
,有趣吗?
正如注释 gtk_init()
中所述,也期望 argv
以 NULL
终止。
最后一个问题是 ffi_type_uint
是错误的类型,在这种情况下您必须使用 ffi_type_pointer
(顺便说一句 int
需要 ffi_type_sint
)。
所以最终的固定代码是:
#include <ffi.h>
#include <gtk/gtk.h>
void test(void);
int main(void) { test(); }
void test(void) {
ffi_type *arg_types[] = {&ffi_type_pointer, &ffi_type_pointer};
ffi_cif cif;
ffi_status status =
ffi_prep_cif(&cif, FFI_DEFAULT_ABI, sizeof arg_types / sizeof *arg_types,
&ffi_type_void, arg_types);
if (status != FFI_OK) {
printf("Failed to prep_ffi\n");
return;
}
// bad we don't check malloc() !!! ;)
int argc = 4;
char **argv = malloc(sizeof *argv * (argc + 1));
#define X(x) strcpy(malloc(sizeof x), x);
argv[0] = X("test");
argv[1] = X("--gtk-debug");
argv[2] = X("misc");
argv[3] = X("last");
argv[4] = NULL;
#undef X
int *p_argc = &argc; // This is what expect gtk_init
char ***p_argv = &argv;
void *arg_values[] = {&p_argc, &p_argv}; // so ffi need their address
ffi_arg result;
ffi_call(&cif, FFI_FN(>k_init), &result, arg_values);
for (int i = 0; i < argc; i++) {
printf("%s\n", argv[i]);
free(argv[i]);
}
free(argv);
}
免责声明:未经测试。
关于c - 如何使用 char** 指针进行 FFI 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50884472/