From: WATANABE Hirofumi Date: 2003-01-09T18:56:45+09:00 Subject: [ruby-dev:19337] Re: [Ruby/DL] Bignum to ... わたなべです。 Takaaki Tateishi writes: > > % cat foo.c > > int foo(int i) > > ここの型なんですが,unsinged int ではなくて int ですか? ここは32ビットの整数の受け渡しだけを重視していたので、 signedでもunsignedでもどっちでもいいと思ったけど、 unsignedにすべきでしたね。すみません。 > > となります。これはNUM2INTやNUM2LONGを使っているためで、 > > 0x80000000から0xFFFFFFFFまでが渡せません。 > > 相手が int だからそれで良いような気がします.また,unsigned > int の場合,pack/unpack を使って変換すれば良いと考えています. > > [0xFFFFFFFF].pack("I").unpack("i") > => [-1] > > という感じです. なるほど。このあたりの考えかたが違っていたわけですね。 だったらunsignedもサポートして欲しいです。 たとえばuIという指定なら0から0xFFFFFFFFまで素直に書けるとか。 それはそれとしてWin32API.rbの場合、互換性を考えるとこう書けそうです。 #'S'は今の仕様 require 'dl' class Win32API DLL = {} def initialize(dllname, func, import, export = "0") prototype = (export + import.to_s).tr("VPpNnLlIi", "0SSI") handle = DLL[dllname] ||= DL::Handle.new(dllname) begin @sym = handle.sym(func, prototype) rescue RuntimeError @sym = handle.sym(func + "A", prototype) end end def call(*args) import = @sym.proto[1..-1] || "" args.each_with_index do |x, i| args[i] = nil if x == 0 and import[i] == ?S args[i], = [x].pack("I").unpack("i") if import[i] == ?I end ret, = @sym.call(*args) return ret || 0 end alias Call call end