c - 如何使用 char** 指针进行 FFI 调用?

标签 c ffi

我正在尝试进行 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() 中所述,也期望 argvNULL 终止。

最后一个问题是 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(&gtk_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/

相关文章:

c中二维数组中整数的连续间隔输入

c - c中数组分配的内存的哪一部分

ruby - 无法通过 rvm bundle install 安装 ffi 1.9.0 - OSX 10.8.4

performance - 从 Haskell 中的 monadic 流中榨取更多性能

c - 在 Linux 上跨进程共享数据

python - 实现 Every-to-Every 交互的有效方法?

c - 如何找到字符串中唯一字符的数量?

ruby - 如何更改 Ruby 中 FFI 调用的 STDOUT?

rust - 我如何在 Rust 代码中表示 C 的 "unsigned negative"值?

haskell - 尽管没有显示错误,GHC 不会生成二进制文件