2

私が書いた ac 関数を呼び出す ruby​​ gem を作りたいです。例えば:

int func(int x)
{
  return x * 2;
}

これは、私の ruby​​gem の ac ファイルにあります。次に、ffi インターフェイスでラップすることにより、Ruby で呼び出すことができるようにしたいと考えています。

  module TestModule
    extend FFI::Library
    ffi_lib 'MyLib'
    attach_function 'func', [:int], :int
  end

ただし、これを設定する方法がわからないため、gem がインストールされたときに c ファイルがコンパイルされてライブラリ (「MyLib」という名前) になり、ffi がライブラリを検出して上記のコードで使用します。 .

誰かがこれを行う方法を知っていますか、またはこれを行うためのより良い方法はありますか? Ruby を拡張する標準的な方法 (The Pragmatic Programmer's Guide の Ruby の拡張セクションで説明されている) を使用したくないことに注意してください。

この質問にとって重要な場合、私は自分の宝石を作るために宝石商を使用しています。

4

1 に答える 1

5

nanothiefでは、最初にCコンパイラに相談してCコードをライブラリにコンパイルする必要があります。

たとえば、上記の関数がMyLib.cという名前のファイルにあり、GCCを使用していると仮定します。

$ gcc -c MyLib.c

...結果としてMyLib.oオブジェクトファイルになります

$ gcc -shared -o MyLib.so MyLib.o

...これにより、ライブラリファイルであるMyLib.so共有オブジェクトが生成されます(ただし、このライブラリは私の環境では正常にコンパイルされる可能性がありますが、環境では機能しない可能性があることに注意してください)。

次に、Rubyコードで、FFIgemを次のようにロードする必要があります。

require 'ffi'

ただし、FFI / Rubyアプローチを使用することの利点は、gemユーザーの環境について推測する必要がないことです。したがって、ほとんどの場合、ffi_libを使用してロードするライブラリは、すでにコンパイルされており、gemユーザーのマシンのライブラリパスのどこかに存在していることが期待されます。

C拡張機能を使用する場合は、Cソースをgemと一緒にパッケージ化し、gemユーザーにCソースを自分でコンパイルしてもらう必要があります。ユーザーが環境のCコンパイラーにアクセスできない場合、またはユーザーがJRubyを使用している場合(C拡張機能、IIRCのサポートは制限されています)、これは機能しない可能性があります。

興味があれば、FFIを活用した私が書いたこの宝石を見てください。

于 2011-04-08T03:19:04.663 に答える