RubyのC拡張を作成する時、int
や long
に関しては INT2NUM
NUM2INT
LONG2NUM
NUM2LONG
などの便利なマクロが用意されているが、int32_t
uint32_t
などの型と相互に変換するマクロは用意されていない。intやlongなどの型のサイズはシステムによって変わる可能性もゼロではない。そこで、ruby-jpで質問したところ、
マクロを使用すればいいという回答を頂いた。すこし厄介ですが、こんな感じになると思います。
#define SIZEOF_INT32 4
#define SIZEOF_INT64 8
#if SIZEOF_SHORT == SIZEOF_INT32
#define NUM2UINT32 NUM2USHORT
#define NUM2INT32 NUM2SHORT
#define UINT32_2NUM USHORT2NUM
#define INT32_2NUM SHORT2NUM
#elif SIZEOF_INT == SIZEOF_INT32
#define NUM2UINT32 NUM2UINT
#define NUM2INT32 NUM2INT
#define UINT32_2NUM UINT2NUM
#define INT32_2NUM INT2NUM
#elif SIZEOF_LONG == SIZEOF_INT32
#define NUM2UINT32 NUM2ULONG
#define NUM2INT32 NUM2LONG
#define UINT32_2NUM ULONG2NUM
#define INT32_2NUM LONG2NUM
#else
#error "Neither int, long, nor short is the same size as int32_t"
#endif
#if SIZEOF_INT == SIZEOF_INT64
#define NUM2UINT64 NUM2UINT
#define NUM2INT64 NUM2INT
#define UINT64_2NUM UINT2NUM
#define INT64_2NUM INT2NUM
#elif SIZEOF_LONG == SIZEOF_INT64
#define NUM2UINT64 NUM2ULONG
#define NUM2INT64 NUM2LONG
#define UINT64_2NUM ULONG2NUM
#define INT64_2NUM LONG2NUM
#elif SIZEOF_LONGLONG == SIZEOF_INT64
#define NUM2UINT64 NUM2ULL
#define NUM2INT64 NUM2LL
#define UINT64_2NUM ULL2NUM
#define INT64_2NUM LL2NUM
#else
#error "Neither int, long, nor short is the same size as int64_t"
#endif
けっこう面倒くさい。
もしもこういったものを簡単にやりたいという要望が多ければ、将来的には UINT32TONUM
などのマクロがRuby本体に入る可能性もあるかも知れませんとのことです。
この記事は以上です。