小松です。

In the message of [ruby-dev:8722] [mswin32] Win32API
    on 1999/12/25 00:39:02 KANEKO Naoshi <wbs01621 / mail.wbs.ne.jp> wrote:
|木村さん、小松さん、すみませんがこれも検証して
|いただけますか?

[ruby-dev:8639]にも書きましたが、NUM2ULONG (rb_num2ulong) に
負のBignumを与えられた場合、その絶対値を返すのがそもそもの
問題だと思います。

ということで、numeric.cの変更を希望。

--- ruby-1.4.3.dist/numeric.c	Mon Dec  6 18:03:32 1999
+++ ruby-1.4.3/numeric.c	Sun Dec 26 18:29:16 1999
@@ -711,4 +711,5 @@ rb_num2ulong(val)
 {
     if (TYPE(val) == T_BIGNUM) {
+	if (!RBIGNUM(val)->sign) return -rb_big2ulong(val);
 	return rb_big2ulong(val);
     }

|-		    mov     eax, dword ptr pParam
|+		    mov     eax, pParam

なるほど、dword ptrは必要無いと。
無くても生成されるコードは同じで、この上の方の_T_INTEGERの処理では
dword ptrありませんし。

趣味としては、[ruby-dev:8639]のruby.hの変更がすでに取り込まれて
いるので、以下のUINT2NUM()を使うバージョンにしたいです。
ついでに、__CYGWIN32__をやめて__CYGWIN__にして、スタイルを
調整したい。

動くという点では、今まで出た、
  o [ruby-dev:8633]のWin32API.cの変更
  o [ruby-dev:8722]のWin32API.cの変更
  o 上のnumeric.cの変更
  o [ruby-dev:8639]のruby.hの変更 + 以下のWin32API.cのパッチ
のどれを使っても問題ないです。

ただ、numeric.cの変更がないと、以下のように引数の方の処理が
期待通りに動かないです。

C:\lang\ruby>type x.rb
require "Win32API"
GetLastError = Win32API.new("kernel32", "GetLastError", [], 'L')
SetLastError = Win32API.new("kernel32", "SetLastError", ['L'], 'V')
SetLastError.Call -1
p GetLastError.Call
SetLastError.Call -2147483647
p GetLastError.Call
SetLastError.Call 0x80000001
p GetLastError.Call

C:\lang\ruby>ruby x.rb
-1
2147483647
-2147483647

C:\lang\ruby>

--- ext/Win32API/Win32API.c.dist Fri Oct 15 17:52:17 1999 +++ ext/Win32API/Win32API.c Sun Dec 26 16:17:11 1999 @@ -69,7 +69,7 @@ Win32API_initialize(self, dllname, proc, RSTRING(proc)->ptr, RSTRING(str)->ptr); } - rb_iv_set(self, "__dll__", INT2NUM((int)hdll)); + rb_iv_set(self, "__dll__", UINT2NUM((unsigned long)hdll)); rb_iv_set(self, "__dllname__", dllname); - rb_iv_set(self, "__proc__", INT2NUM((int)hproc)); + rb_iv_set(self, "__proc__", UINT2NUM((unsigned long)hproc)); a_import = rb_ary_new(); @@ -125,5 +125,5 @@ Win32API_Call(argc, argv, obj) ApiInteger *ApiFunctionInteger; - long lParam; + long lParam; char *pParam; @@ -145,5 +145,5 @@ Win32API_Call(argc, argv, obj) obj_import = rb_iv_get(obj, "__import__"); obj_export = rb_iv_get(obj, "__export__"); - nimport = RARRAY(obj_import)->len; + nimport = RARRAY(obj_import)->len; texport = FIX2INT(obj_export); @@ -166,5 +166,5 @@ Win32API_Call(argc, argv, obj) push eax } -#elif defined(__CYGWIN32__) || defined(__MINGW32__) +#elif defined(__CYGWIN__) || defined(__MINGW32__) asm volatile ("pushl %0" :: "g" (lParam)); #else @@ -185,8 +185,8 @@ Win32API_Call(argc, argv, obj) #if defined(_MSC_VER) || defined(__LCC__) _asm { - mov eax, dword ptr pParam + mov eax, pParam push eax } -#elif defined(__CYGWIN32__) || defined(__MINGW32__) +#elif defined(__CYGWIN__) || defined(__MINGW32__) asm volatile ("pushl %0" :: "g" (pParam)); #else @@ -196,5 +196,4 @@ Win32API_Call(argc, argv, obj) } } - } -- 小松克行 / Katsuyuki Komatsu <komatsu / sarion.co.jp>