From: "Shirai,Kaoru" Date: 2003-11-03T16:12:28+09:00 Subject: [ruby-list:38741] Re: [Win32] GetLastError() with dl.so ----Next_Part(Mon_Nov__3_16:12:09_2003_912)-- Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit 白井です。 > At Fri, 31 Oct 2003 23:50:22 +0900, > > Win32APIのCreateMutexをRuby-1.8.0-mswin32から使おうとして気付いたので > > すが、dl.so(Win32API.soも)でAPIを呼び出した後に、GetLastError()の値が > > 直前の呼び出しに基づいたものになりません。 > > とくに異論がなければ現在のdl.soに関してはある程度互換性がとれて使えれ > ばなんでもいいというスタンスに近いので添付のパッチを取り込もうと思っ > ています. どうもありがとうございます。 > # errnoもそうした方がよいでしょうか? そう思います。mallocが成功時にerrnoをセットしてしまうプラットフォーム もあるかも知れません。GetLastErrorと違いerrnoは変数なので、このように しないと取得できないというのもありますし。 スレッドに対応し( rb_thread_local_aset を使用)、なおかつ DL.last_errno メソッドを追加したものを添付します。DL.last_errno は linux 、 DL.win32_last_error については cygwin,mingw,mswin32 で動作確 認しました。 * errno = DL.last_errno # * Returns value of errno(3) after the last function call of # the current thread. * このスレッドで最後に発生した関数呼び出しの直後の errno(3) の値を返します。 * errcode = DL.win32_last_error # * Returns value of GetLastError() after the last function call of # the current thread. This method is only defined on Windows. * このスレッドで最後に発生した関数呼び出しの直後の GetLastError() の値を 返します。Windows上でのみ定義されています。 -- Shirai,Kaoru Korinkan Ltd. - http://www.korinkan.co.jp/ 「さァ、選挙に行きましょう!」 2003年 衆院選「公開アンケート」全国プロジェクト - 結果公表中 http://www.chikyumura.org/campaigns/election/2003shugiin/ *舞台裏でのデータ入力とHTMLの自動生成にRuby+ERbが活躍しました* ----Next_Part(Mon_Nov__3_16:12:09_2003_912)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dl-sym-win32err-2.diff" Index: sym.c =================================================================== RCS file: /src/ruby/ext/dl/sym.c,v retrieving revision 1.19 diff -u -r1.19 sym.c --- sym.c 29 Mar 2003 02:56:18 -0000 1.19 +++ sym.c 3 Nov 2003 07:10:28 -0000 @@ -3,6 +3,7 @@ */ #include +#include #include "dl.h" VALUE rb_cDLSymbol; @@ -316,6 +317,23 @@ return size; } +ID rb_dl_id_DLErrno; +VALUE +rb_dl_get_last_errno(VALUE self) +{ + return rb_thread_local_aref(rb_thread_current(), rb_dl_id_DLErrno); +} + +#ifdef HAVE_WINDOWS_H +#include +ID rb_dl_id_DLW32Error; +VALUE +rb_dl_win32_get_lasterror(VALUE self) +{ + return rb_thread_local_aref(rb_thread_current(), rb_dl_id_DLW32Error); +} +#endif + VALUE rb_dlsym_call(int argc, VALUE argv[], VALUE self) { @@ -675,6 +693,11 @@ rb_raise(rb_eDLTypeError, "unknown type `%c'", sym->type[0]); } } + + rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLErrno, INT2NUM(errno)); +#ifdef _WIN32 + rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLW32Error, INT2NUM(GetLastError())); +#endif } #else /* defined(DLSTACK) */ switch(ftype){ @@ -835,4 +858,11 @@ 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); + + rb_dl_id_DLErrno = rb_intern("DLErrno"); + rb_define_singleton_method(rb_mDL, "last_errno", rb_dl_get_last_errno, 0); +#ifdef _WIN32 + rb_dl_id_DLW32Error = rb_intern("DLW32Error"); + rb_define_singleton_method(rb_mDL, "win32_last_error", rb_dl_win32_get_lasterror, 0); +#endif } Index: extconf.rb =================================================================== RCS file: /src/ruby/ext/dl/extconf.rb,v retrieving revision 1.11 diff -u -r1.11 extconf.rb --- extconf.rb 23 Oct 2003 08:59:42 -0000 1.11 +++ extconf.rb 3 Nov 2003 07:10:29 -0000 @@ -127,6 +127,13 @@ $dlconfig_h << "#define WITH_TYPE_VOIDP\n" end +if( have_header("windows.h") ) + have_library("kernel32") + have_func("GetLastError", "windows.h") + dlc_define("HAVE_WINDOWS_H") + have_windows_h = true +end + if( have_header("dlfcn.h") ) dlc_define("HAVE_DLFCN_H") have_library("dl") @@ -136,8 +143,7 @@ if( have_func("dlerror") ) dlc_define("HAVE_DLERROR") end -elsif( have_header("windows.h") ) - dlc_define("HAVE_WINDOWS_H") +elsif ( have_windows_h ) have_func("LoadLibrary") have_func("FreeLibrary") have_func("GetProcAddress") ----Next_Part(Mon_Nov__3_16:12:09_2003_912)----