2011-07-11 6 views
2

私はRubyのFFIを使ってGoogleシティハッシュの宝石に付けようとしています。デフォルトのRubyハッシュ関数(murmur_hash 1)に似た、64ビット、128ビットの非暗号化ハッシュですが、もう少し新しいものです。さらに重要なことは、ハッシュにシードを設定できることです。GoogleのCityhash gemはなぜインストールされませんか?

私は私のMac上のデフォルト./configureを使用して/usr/local/libにcityhashをインストールしました。 これは、/usr/local/libにいくつかのライブラリを置く:私は、Mac OS X. を使用しています

-rwxr-xr-x 1 root wheel 13720 Jul 11 15:16 /usr/local/lib/libcityhash.0.dylib 
-rw-r--r-- 1 root wheel 43424 Jul 11 15:16 /usr/local/lib/libcityhash.a 
lrwxr-xr-x 1 root wheel 19 Jul 11 15:16 /usr/local/lib/libcityhash.dylib -> libcityhash.0.dylib 
-rwxr-xr-x 1 root wheel 977 Jul 11 15:16 /usr/local/lib/libcityhash.la 

gccのバージョンでは、デフォルトのMacのgccされていない4.6ですが、私は、あまりにもすることを試みました。

ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-darwin10.6.0] 

FFI(Macのデフォルトのgccでインストールされ、GCC 4.6が動作しない?)

私は私ができる最も簡単なモジュール製:

require 'ffi' 
module MyCityHash 
    extend FFI::Library 

    ffi_lib 'cityhash' 
    attach_function :CityHash64, [:string, :size_t], :uint64  
end 

を私は、しようとすると、任意のRubyのクラスやスクリプトファイルにこのモジュール私はエラーを取得する:

/Users/charlesmartin/.rvm/gems/ruby-1.9.2-p180/gems/ffi-1.0.9/lib/ffi/library.rb:147:in `attach_function': Function 'CityHash64' not found in [libcityhash.dylib] (FFI::NotFoundError) 

CityHash64は内の署名を持っていますcity.h:

uint64 CityHash64(const char *buf, size_t len); 

私は非常にこれをデバッグする方法上の任意の洞察力をいただければ幸いです。

答えて

3

cityhashプロジェクトで簡単に見から、それは彼らがCのシンボルとして表示されませんを意味し、C++、であるように、それが見えます。名前は変更されます(nm libcityhash.dylibを実行すると、これを見ることができます)。

  1. がマングルされた名前は、(nm以下objdumpの使用)しているかワークアウト、およびattach_functionにネイティブ関数名としてそれらを使用する:

    あなたは選択肢のカップルを持っています。例えばNMによって示されるように、「__Z10CityHash64PKcm」はCityHash64ののシンボル名である

    attach_function :CityHash64, :__Z10CityHash64PKcm, [ :string, :size_t ], :uint64 
    

    (注:マングル名は、プラットフォーム間で異なります)。 attach_functionへの最初の引数は、あなたがrubyから呼び出すことができる名前なので、MyCityHash.CityHash64()と呼びます。

  2. アクセスする各関数の先頭に 'extern' C "'を付けて、cityhash関数をCシンボル(したがってruby-ffiで表示)として公開します。例えば

    extern "C" uint64 CityHash64(const char *buf, size_t len); 
    

その後libcityhash.dylibを再構築します。

あなたが他の人に配布する宝石を作成している場合、あなたは、昔ながらのC.

+0

おかげで機能を公開するcityhashのメンテナを説得できない限り、オプション#1を使用する必要があります。私は働くことができませんでしたが、2はうまくいきます。 – Charles

関連する問題