为什么不安装 Google 的 Cityhash gem?
我正在尝试使用 Ruby 的 FFI 附加到 Google cityhash gem;它是 64 位和 128 位非加密哈希,类似于默认的 Ruby 哈希函数 (murmur_hash 1),但更新一点,更重要的是,允许在哈希上设置种子。
我使用 Mac 上的默认 ./configure
将 cityhash 安装到 /usr/local/lib
中。 这会将一些库放在 /usr/local/lib
中:
-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
我使用的是 Mac OS X。 gcc 版本是 4.6,这不是默认的 Mac gcc,但我也尝试过。
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);
我将非常感谢任何关于如何调试它的见解。
I am trying to use Ruby's FFI to attach to the Google cityhash gem; It is a 64 bit, and 128 bit, non-cryptographic hash, similar to the default Ruby hash function (murmur_hash 1), but is a bit more recent, and, more importantly, allows setting the seed on the hash.
I installed cityhash into /usr/local/lib
using the default ./configure
on my Mac.
This places some libraries in /usr/local/lib
:
-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
I am using Mac OS X.
The gcc version is 4.6 which is not the default Mac gcc, but I tried that too.
ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-darwin10.6.0]
ffi (installed with default gcc on mac, gcc 4.6 doesn't work?)
I made the simplest module that I could:
require 'ffi'
module MyCityHash
extend FFI::Library
ffi_lib 'cityhash'
attach_function :CityHash64, [:string, :size_t], :uint64
end
but when I try to include this module into any Ruby class or script file I get the error:
/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 has the signature in city.h:
uint64 CityHash64(const char *buf, size_t len);
I would greatly appreciate any insight on how to debug this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
快速浏览一下 cityhash 项目,它看起来像是 C++,这意味着它们作为 C 符号不可见。名称将被破坏(如果运行“nm libcityhash.dylib”,您可以看到这一点)。
您有几个选择:
找出损坏的名称是什么(使用 nm 或 objdump),并将它们用作 Attach_function 的本机函数名称。例如
其中“__Z10CityHash64PKcm”是CityHash64的符号名称,如nm所示(注意:不同平台的名称不同)。 Attach_function 的第一个参数是您希望它可以从 ruby 调用的名称,因此您仍然可以将其称为 MyCityHash.CityHash64()。
通过在要访问的每个函数前加上“extern“C””前缀,将 cityhash 函数公开为 C 符号(因此对 ruby-ffi 可见)。例如
然后重建libcityhash.dylib。
如果您要创建一个 gem 分发给其他人,那么您必须使用选项 #1,除非您可以说服 cityhash 维护者将函数公开给普通的旧 C。
From a quick look at the cityhash project, it looks like it is C++, which means they are not visible as C symbols. The names will be mangled (you can see this if you run 'nm libcityhash.dylib').
You have a couple of choices:
Work out what the mangled names are (using nm or objdump), and use them as the native function name to attach_function. e.g.
where "__Z10CityHash64PKcm" is the symbol name of of CityHash64 as shown by nm (note: the mangled name differs between platforms). The first arg to attach_function is the name you want it to be callable as from ruby, so you would still call it as MyCityHash.CityHash64().
Expose the cityhash functions as C symbols (and hence visible to ruby-ffi) by prefixing each function you want to access with 'extern "C"'. e.g.
Then rebuild libcityhash.dylib.
If you're creating a gem to distribute to others, then you'll have to use option #1, unless you can convince the cityhash maintainers to expose the functions to plain old C.