From: "Shirai,Kaoru" Date: 2003-10-31T23:50:22+09:00 Subject: [ruby-list:38712] [Win32] GetLastError() with dl.so ----Next_Part(Fri_Oct_31_23:50:07_2003_888)-- Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit 白井です。 Win32APIのCreateMutexをRuby-1.8.0-mswin32から使おうとして気付いたので すが、dl.so(Win32API.soも)でAPIを呼び出した後に、GetLastError()の値が 直前の呼び出しに基づいたものになりません。 ================================================================ require "dl/import" module Win32 extend DL::Importable dlload "kernel32.dll" extern "void SetLastError(DWORD)" extern "DWORD GetLastError()" end #/Win32 Win32.setLastError(1234) p Win32.getLastError #=>0 ================================================================ おそらく、2つのdl_sym_call()の間に別のAPI呼び出しが発生しているのだと 思います。CreateMutexなどを使う場合はエラーコードを判定したいので、こ れだと少し困ります。拡張ライブラリを書けば別なんですが。 とりあえず、応急的にsym.cをいじってDL.win32_last_errorメソッドを追加し て取得できるようにしてみました。(スレッド非対応)cygwin,mingw版では動 作確認していませんが、これで取得できるようにはなりました。 Win32.setLastError(1234) p DL.win32_last_error #=>1234 p Win32.getLastError #=>0 何か他に良いアプローチは無いでしょうか。 -- Shirai,Kaoru Korinkan Ltd. - http://www.korinkan.co.jp/ ----Next_Part(Fri_Oct_31_23:50:07_2003_888)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dl-sym-win32err.diff" Index: ext/dl/sym.c =================================================================== RCS file: /src/ruby/ext/dl/sym.c,v retrieving revision 1.19 diff -u -r1.19 sym.c --- ext/dl/sym.c 29 Mar 2003 02:56:18 -0000 1.19 +++ ext/dl/sym.c 31 Oct 2003 14:37:41 -0000 @@ -316,6 +316,16 @@ return size; } +#ifdef HAVE_WINDOWS_H +#include +DWORD rb_dl_win32_lasterror = 0; +VALUE +rb_dl_win32_get_lasterror(VALUE self) +{ + return INT2NUM(rb_dl_win32_lasterror); +} +#endif + VALUE rb_dlsym_call(int argc, VALUE argv[], VALUE self) { @@ -675,6 +685,9 @@ rb_raise(rb_eDLTypeError, "unknown type `%c'", sym->type[0]); } } +#ifdef _WIN32 + rb_dl_win32_lasterror = GetLastError(); +#endif } #else /* defined(DLSTACK) */ switch(ftype){ @@ -835,4 +848,8 @@ rb_define_method(rb_cDLSymbol, "to_s", rb_dlsym_cproto, 0); rb_define_method(rb_cDLSymbol, "to_ptr", rb_dlsym_to_ptr, 0); rb_define_method(rb_cDLSymbol, "to_i", rb_dlsym_to_i, 0); + +#ifdef _WIN32 + rb_define_singleton_method(rb_mDL, "win32_last_error", rb_dl_win32_get_lasterror, 0); +#endif } ----Next_Part(Fri_Oct_31_23:50:07_2003_888)----