为了使用 Ruby 的String.unpack 解压缩具有混合双精度和整数的复杂二进制字符串,我需要确定二进制字符串中的偏移量。通常,双精度数是 8 个字节,整数是 4 个字节,但为了使我的代码与机器无关,我想从我的 Ruby 代码中查询这些大小。
从 Ruby 中确定整数和双精度的大小的最简单方法是什么,即请求对 Csizeof( type )
方法的请求响应?
为了使用 Ruby 的String.unpack 解压缩具有混合双精度和整数的复杂二进制字符串,我需要确定二进制字符串中的偏移量。通常,双精度数是 8 个字节,整数是 4 个字节,但为了使我的代码与机器无关,我想从我的 Ruby 代码中查询这些大小。
从 Ruby 中确定整数和双精度的大小的最简单方法是什么,即请求对 Csizeof( type )
方法的请求响应?
Array#pack
通过使用的逆方法,我找到了一个可行的解决方案String#unpack
。通过打包一个由 1 个整数或 1 个双精度组成的字符串,可以从 ruby 本身确定整数和双精度的大小,这与使用sizeof(int)
or的结果相同sizeof(double)
(因为Array#pack
在 C 中实现了):
[1.to_i].pack("i").size # 4
[1.to_f].pack("d").size # 8
这很明显,我可能错过了这一点:
puts 1.size #=> 4
puts (256**10 - 1).size #=> 12
我不熟悉 Ruby 语言或其构建/分发系统。但是,Rake的存在表明可以在包安装时创建自定义文件 - 例如将以下命令的结果导出为 Ruby 常量的配置文件:
echo __SIZEOF_INT__ | gcc -E -P -
echo __SIZEOF_DOUBLE__ | gcc -E -P -
我目前的解决方案是有一个小的 C 程序,sizeofdouble.c
:
#include <stdio.h>
int main() {
printf( "%lu", sizeof(double) );
}
其中,当编译为sizeofdouble
可执行文件时,可以从 ruby 调用
sizeofdouble = `./sizeofdouble`.to_i
但这是一个丑陋的黑客,而不是这个问题的干净解决方案。
我知道我在这里聚会迟到了,但是 ruby 的Fiddle
库将您可能想要的所有数据类型的大小公开为常量。以下是我的系统(64 位 MacOS 10.13)上的结果:
require 'fiddle'
Fiddle::SIZEOF_SHORT # => 2
Fiddle::SIZEOF_INT # => 4
Fiddle::SIZEOF_DOUBLE # => 8
Fiddle::SIZEOF_SIZE_T # => 8
Fiddle::SIZEOF_SSIZE_T # => 8
请参阅:https ://ruby-doc.org/stdlib-2.5.0/libdoc/fiddle/rdoc/Fiddle.html#SIZEOF_CHAR