将指向一个C函数的指针作为参数传递给另一个函数

时间:2015-01-23 05:15:23

标签: ruby ffi

我正在使用FFI gem,以便我可以直接从我的Ruby程序访问C库中的函数。如果C库有一个接受函数指针参数的函数,并且它有第二个函数,该函数具有正确的签名,那么我如何将指针作为第一个函数的参数传递给第二个函数?

我尝试了什么

这是我到目前为止所尝试的内容。为简化起见,我在一个名为bar.c的文件中编写了我自己非常简单的C库:

#include <stdio.h>

typedef int bar_func();

int bar1()
{
    return 7;
}

int bar2(bar_func * f)
{
    printf("f=%p, bar2=%p\n", f, bar1);
    return f() + f();
}

我是通过运行gcc -std=gnu99 -fPIC -shared bar.c -o bar.so

在Arch Linux下编译的

我的目标是将指向bar1的指针作为参数传递给bar2。我希望bar2打印两个相同的指针,然后返回14.

所以我使用Ruby 2.2.0p0和ffi 1.9.6运行这个程序:

require 'ffi'

module Bar
  extend ::FFI::Library
  ffi_lib './bar.so'
  callback :bar_func, [], :int
  attach_function :bar1, [], :int
  attach_function :bar2, [:bar_func], :int

  puts bar2(method(:bar1))   # => 14
end

当我运行程序时,这是我得到的输出:

f=0x7f563ce46000, bar1=0x7f563af7d6e0
14

它给出了正确的返回值,但是你可以看到传递给bar2函数的函数指针明显不等于bar1,因为在第一行打印的两个函数指针是不同的

1 个答案:

答案 0 :(得分:0)

我在FFI::Library documentation看到了一个提示。它说attach_function返回FFI::VariadicInvoker个对象。我做了一个有根据的猜测,你可以通过它而不是一个proc,它起作用了。

module Bar
  extend ::FFI::Library
  ffi_lib './bar.so'
  callback :bar_func, [], :int
  Bar1Invoker = attach_function :bar1, [], :int
  attach_function :bar2, [:bar_func], :int

  puts bar2(Bar1Invoker)   # => 14
end

我得到了所需的输出:

f=0x7f949ed7d6e0, bar1=0x7f949ed7d6e0
14

我已经编辑了FFI wiki上的Callbacks页面以获取此信息。