From djberg96 at gmail.com Sat Apr 7 08:21:50 2012 From: djberg96 at gmail.com (Daniel Berger) Date: Sat, 7 Apr 2012 02:21:50 -0600 Subject: [Win32utils-devel] FFI and msvcrt Message-ID: Hi, I've been using FFI with a Ruby 1.9.3 built with MSVC++ and it's been working well. One thing I've run into though is this: ffi_lib :msvcrt But that's not the runtime I want. But I don't want to hard code the runtime name either. I realize I could parse it out of RbConfig, but I was hoping for something nicer. Is there a way we could create an analogue to FFI::Library::LIBC for the MSVC runtime? Something like FFI::Library::MSVCRT ? Regards, Dan From phasis at gmail.com Sat Apr 7 14:47:50 2012 From: phasis at gmail.com (Heesob Park) Date: Sat, 7 Apr 2012 23:47:50 +0900 Subject: [Win32utils-devel] FFI and msvcrt In-Reply-To: References: Message-ID: Hi, 2012/4/7 Daniel Berger > Hi, > > I've been using FFI with a Ruby 1.9.3 built with MSVC++ and it's been > working well. One thing I've run into though is this: > > ffi_lib :msvcrt > > But that's not the runtime I want. But I don't want to hard code the > runtime name either. I realize I could parse it out of RbConfig, but I > was hoping for something nicer. > > Is there a way we could create an analogue to FFI::Library::LIBC for > the MSVC runtime? Something like FFI::Library::MSVCRT ? > > I can find msvcrt runtime like this: def find_msvcrt require 'rbconfig' RbConfig::CONFIG['RUBY_SO_NAME'].split('-')[-2]+'.dll' end Did you mean this seems ugly? Well, I cannot find a nicer method than above one. Regards, Park Heesob -------------- next part -------------- An HTML attachment was scrubbed... URL: From luislavena at gmail.com Sat Apr 7 15:10:45 2012 From: luislavena at gmail.com (Luis Lavena) Date: Sat, 7 Apr 2012 12:10:45 -0300 Subject: [Win32utils-devel] FFI and msvcrt In-Reply-To: References: Message-ID: On Sat, Apr 7, 2012 at 11:47 AM, Heesob Park wrote: > Hi, > > > 2012/4/7 Daniel Berger >> >> Hi, >> >> I've been using FFI with a Ruby 1.9.3 built with MSVC++ and it's been >> working well. One thing I've run into though is this: >> >> ffi_lib :msvcrt >> >> But that's not the runtime I want. But I don't want to hard code the >> runtime name either. I realize I could parse it out of RbConfig, but I >> was hoping for something nicer. >> >> Is there a way we could create an analogue to FFI::Library::LIBC for >> the MSVC runtime? Something like FFI::Library::MSVCRT ? >> > > I can find msvcrt runtime like this: > > def find_msvcrt > require 'rbconfig' > RbConfig::CONFIG['RUBY_SO_NAME'].split('-')[-2]+'.dll' > end > > Did you mean this seems ugly? > > Well, I cannot find a nicer method than above one. > Maybe something that correct the MSVCRT issue instead? Here is the source of FFI::Library::MSVCRT: https://github.com/ffi/ffi/blob/master/lib/ffi/platform.rb#L92-98 Perhaps something that uses RbConfig::CONFIG["RUBY_SO_NAME"] and extract from it? I bet Wayne (from FFI project) would love the contribution. -- Luis Lavena AREA 17 - Perfection in design is achieved not when there is nothing more to add, but rather when there is nothing more to take away. Antoine de Saint-Exup?ry From djberg96 at gmail.com Sat Apr 7 17:21:12 2012 From: djberg96 at gmail.com (Daniel Berger) Date: Sat, 7 Apr 2012 11:21:12 -0600 Subject: [Win32utils-devel] FFI and msvcrt In-Reply-To: References: Message-ID: On Sat, Apr 7, 2012 at 8:47 AM, Heesob Park wrote: > Hi, > > > 2012/4/7 Daniel Berger >> >> Hi, >> >> I've been using FFI with a Ruby 1.9.3 built with MSVC++ and it's been >> working well. One thing I've run into though is this: >> >> ffi_lib :msvcrt >> >> But that's not the runtime I want. But I don't want to hard code the >> runtime name either. I realize I could parse it out of RbConfig, but I >> was hoping for something nicer. >> >> Is there a way we could create an analogue to FFI::Library::LIBC for >> the MSVC runtime? Something like FFI::Library::MSVCRT ? >> > > I can find msvcrt runtime like this: > > def find_msvcrt > require 'rbconfig' > RbConfig::CONFIG['RUBY_SO_NAME'].split('-')[-2]+'.dll' > end > > Did you mean this seems ugly? > > Well, I cannot find a nicer method than above one. Ok, thanks. I thought maybe there was a better way. I've submitted a pull request: https://github.com/ffi/ffi/pull/199 It does feel a little funny overloading LIBC like that, but I guess I'm ok with it. :) Thanks again. Dan From djberg96 at gmail.com Tue Apr 10 15:29:43 2012 From: djberg96 at gmail.com (Daniel Berger) Date: Tue, 10 Apr 2012 09:29:43 -0600 Subject: [Win32utils-devel] FFI and DWORD Message-ID: Hi, A DWORD is declared as: typedef unsigned long DWORD; However, the docs also say that it's a 32-bit unsigned integer. The range is 0 through 4294967295 decimal. When using FFI should I declare a DWORD as :ulong or :uint? Regards, Dan From phasis at gmail.com Tue Apr 10 15:48:41 2012 From: phasis at gmail.com (Heesob Park) Date: Wed, 11 Apr 2012 00:48:41 +0900 Subject: [Win32utils-devel] FFI and DWORD In-Reply-To: References: Message-ID: Hi, 2012/4/11 Daniel Berger > Hi, > > A DWORD is declared as: typedef unsigned long DWORD; > > However, the docs also say that it's a 32-bit unsigned integer. The > range is 0 through 4294967295 decimal. > > When using FFI should I declare a DWORD as :ulong or :uint? > > > I think DWORD should be :ulong. In the header file WinDef.h of Platform SDK, I can see typedef unsigned long DWORD; Also refer to python's wintypes.py http://coverage.livinglogic.de/Lib/ctypes/wintypes.py.html Regards, Park Heesob -------------- next part -------------- An HTML attachment was scrubbed... URL: From djberg96 at gmail.com Wed Apr 11 10:02:25 2012 From: djberg96 at gmail.com (Daniel Berger) Date: Wed, 11 Apr 2012 04:02:25 -0600 Subject: [Win32utils-devel] FFI and DWORD In-Reply-To: References: Message-ID: On Tue, Apr 10, 2012 at 9:48 AM, Heesob Park wrote: > Hi, > > 2012/4/11 Daniel Berger >> >> Hi, >> >> A DWORD is declared as: typedef unsigned long DWORD; >> >> However, the docs also say that it's a 32-bit unsigned integer. The >> range is 0 through 4294967295 decimal. >> >> When using FFI should I declare a DWORD as :ulong or :uint? >> >> > > I think DWORD should be :ulong. > > In the header file WinDef.h of Platform SDK, I can see > > typedef unsigned long ? ? ? DWORD; > > Also refer to python's > wintypes.py?http://coverage.livinglogic.de/Lib/ctypes/wintypes.py.html Ok, thanks, that's what I've been using. Regards, Dan From djberg96 at gmail.com Wed Apr 11 16:16:48 2012 From: djberg96 at gmail.com (Daniel Berger) Date: Wed, 11 Apr 2012 10:16:48 -0600 Subject: [Win32utils-devel] FFI and errno on Windows Message-ID: I'm a bit confused by error handling for posixy functions on Windows. Consider the following code where I'm intentionally passing a bad template to _mktemp. The docs say it should return EINVAL. My first problem is not knowing exactly what the docs mean when they talk about EINVAL on Windows. My second problem is that _get_errno returns a different value that FFI.errno, and FFI.errno seems to return the same value as GetLastError(). require 'ffi' class Windows extend FFI::Library ffi_lib FFI::Library::LIBC attach_function :_mktemp, [:pointer], :string attach_function :_get_errno, [:pointer], :int ffi_lib :kernel32 attach_function :GetLastError, [], :int def self.temp(template) result = _mktemp(template) err = get_err_num # 22 #err = FFI.errno # 158 #err = GetLastError() # 158 if result.nil? raise SystemCallError, err, '_mktemp' end result end def self.get_err_num ptr = FFI::MemoryPointer.new(:int) if _get_errno(ptr) != 0 raise SystemCallError, FFI.errno, '_get_errno' end ptr.read_int end end Windows.temp('xx') Any insight on the subject of GetLastError vs _get_errno would be greatly appreciated. My google skills seem to be failing. Regards, Dan From phasis at gmail.com Sun Apr 15 14:29:42 2012 From: phasis at gmail.com (Heesob Park) Date: Sun, 15 Apr 2012 23:29:42 +0900 Subject: [Win32utils-devel] FFI and errno on Windows In-Reply-To: References: Message-ID: Hi, 2012/4/12 Daniel Berger > I'm a bit confused by error handling for posixy functions on Windows. > Consider the following code where I'm intentionally passing a bad > template to _mktemp. The docs say it should return EINVAL. My first > problem is not knowing exactly what the docs mean when they talk about > EINVAL on Windows. My second problem is that _get_errno returns a > different value that FFI.errno, and FFI.errno seems to return the same > value as GetLastError(). > > require 'ffi' > class Windows > extend FFI::Library > ffi_lib FFI::Library::LIBC > > attach_function :_mktemp, [:pointer], :string > attach_function :_get_errno, [:pointer], :int > > ffi_lib :kernel32 > > attach_function :GetLastError, [], :int > > def self.temp(template) > result = _mktemp(template) > > err = get_err_num # 22 > #err = FFI.errno # 158 > #err = GetLastError() # 158 > > if result.nil? > raise SystemCallError, err, '_mktemp' > end > > result > end > > def self.get_err_num > ptr = FFI::MemoryPointer.new(:int) > > if _get_errno(ptr) != 0 > raise SystemCallError, FFI.errno, '_get_errno' > end > > ptr.read_int > end > end > > Windows.temp('xx') > > Any insight on the subject of GetLastError vs _get_errno would be > greatly appreciated. My google skills seem to be failing. > > As you know, _mktemp is a function of C Runtime Library and provides compatibility with mktemp of Linux. According to the Linux manual page ( http://www.kernel.org/doc/man-pages/online/pages/man3/mktemp.3.html): EINVAL means that the last six characters of template were not XXXXXX. FFI.errno is same to GetLastError() on Windows by the following lines of LastError.c void rbffi_save_errno(void) { int error = 0; #ifdef _WIN32 error = GetLastError(); #else error = errno; #endif thread_data_get()->td_errno = error; } I think errno and GetLastError must be separated Windows. The doc of mktemp mentioned only errno value. Thus GetLastError() value is undetermined in this case. Regards, Park Heesob -------------- next part -------------- An HTML attachment was scrubbed... URL: From djberg96 at gmail.com Mon Apr 16 15:06:59 2012 From: djberg96 at gmail.com (Daniel Berger) Date: Mon, 16 Apr 2012 11:06:59 -0400 Subject: [Win32utils-devel] FFI and errno on Windows In-Reply-To: References: Message-ID: On Sun, Apr 15, 2012 at 10:29 AM, Heesob Park wrote: > Hi, > > 2012/4/12 Daniel Berger >> >> I'm a bit confused by error handling for posixy functions on Windows. >> Consider the following code where I'm intentionally passing a bad >> template to _mktemp. The docs say it should return EINVAL. My first >> problem is not knowing exactly what the docs mean when they talk about >> EINVAL on Windows. My second problem is that _get_errno returns a >> different value that FFI.errno, and FFI.errno seems to return the same >> value as GetLastError(). >> >> require 'ffi' >> class Windows >> ?extend FFI::Library >> ?ffi_lib FFI::Library::LIBC >> >> ?attach_function :_mktemp, [:pointer], :string >> ?attach_function :_get_errno, [:pointer], :int >> >> ?ffi_lib :kernel32 >> >> ?attach_function :GetLastError, [], :int >> >> ?def self.temp(template) >> ? ?result = _mktemp(template) >> >> ? ?err = get_err_num # 22 >> ? ?#err = FFI.errno # 158 >> ? ?#err = GetLastError() # 158 >> >> ? ?if result.nil? >> ? ? ?raise SystemCallError, err, '_mktemp' >> ? ?end >> >> ? ?result >> ?end >> >> ?def self.get_err_num >> ? ?ptr = FFI::MemoryPointer.new(:int) >> >> ? ?if _get_errno(ptr) != 0 >> ? ? ?raise SystemCallError, FFI.errno, '_get_errno' >> ? ?end >> >> ? ?ptr.read_int >> ?end >> end >> >> Windows.temp('xx') >> >> Any insight on the subject of GetLastError vs _get_errno would be >> greatly appreciated. My google skills seem to be failing. >> > > As you know, _mktemp is a function of C Runtime Library and provides > compatibility with mktemp of Linux. > According to the Linux manual page > (http://www.kernel.org/doc/man-pages/online/pages/man3/mktemp.3.html): > > ?EINVAL means that the last six characters of template were not XXXXXX. > > > FFI.errno is same to GetLastError() on Windows by the following lines of > LastError.c > > void > rbffi_save_errno(void) > { > ? ? int error = 0; > > #ifdef _WIN32 > ? ? error = GetLastError(); > #else > ? ? error = errno; > #endif > > ? ? thread_data_get()->td_errno = error; > } > > I think errno and GetLastError must be separated Windows. > > The doc of mktemp mentioned only errno value.?Thus GetLastError() value is > undetermined in this case. I didn't quite understand you. Do you mean the current code for FFI.errno is wrong? Should it be replaced with _get_errno? Or is it simply up to library authors to know which one to use? Regards, Dan From phasis at gmail.com Tue Apr 17 00:38:54 2012 From: phasis at gmail.com (Heesob Park) Date: Tue, 17 Apr 2012 09:38:54 +0900 Subject: [Win32utils-devel] FFI and errno on Windows In-Reply-To: References: Message-ID: Hi, 2012/4/17 Daniel Berger > On Sun, Apr 15, 2012 at 10:29 AM, Heesob Park wrote: > > Hi, > > > > 2012/4/12 Daniel Berger > >> > >> I'm a bit confused by error handling for posixy functions on Windows. > >> Consider the following code where I'm intentionally passing a bad > >> template to _mktemp. The docs say it should return EINVAL. My first > >> problem is not knowing exactly what the docs mean when they talk about > >> EINVAL on Windows. My second problem is that _get_errno returns a > >> different value that FFI.errno, and FFI.errno seems to return the same > >> value as GetLastError(). > >> > >> require 'ffi' > >> class Windows > >> extend FFI::Library > >> ffi_lib FFI::Library::LIBC > >> > >> attach_function :_mktemp, [:pointer], :string > >> attach_function :_get_errno, [:pointer], :int > >> > >> ffi_lib :kernel32 > >> > >> attach_function :GetLastError, [], :int > >> > >> def self.temp(template) > >> result = _mktemp(template) > >> > >> err = get_err_num # 22 > >> #err = FFI.errno # 158 > >> #err = GetLastError() # 158 > >> > >> if result.nil? > >> raise SystemCallError, err, '_mktemp' > >> end > >> > >> result > >> end > >> > >> def self.get_err_num > >> ptr = FFI::MemoryPointer.new(:int) > >> > >> if _get_errno(ptr) != 0 > >> raise SystemCallError, FFI.errno, '_get_errno' > >> end > >> > >> ptr.read_int > >> end > >> end > >> > >> Windows.temp('xx') > >> > >> Any insight on the subject of GetLastError vs _get_errno would be > >> greatly appreciated. My google skills seem to be failing. > >> > > > > As you know, _mktemp is a function of C Runtime Library and provides > > compatibility with mktemp of Linux. > > According to the Linux manual page > > (http://www.kernel.org/doc/man-pages/online/pages/man3/mktemp.3.html): > > > > EINVAL means that the last six characters of template were not XXXXXX. > > > > > > FFI.errno is same to GetLastError() on Windows by the following lines of > > LastError.c > > > > void > > rbffi_save_errno(void) > > { > > int error = 0; > > > > #ifdef _WIN32 > > error = GetLastError(); > > #else > > error = errno; > > #endif > > > > thread_data_get()->td_errno = error; > > } > > > > I think errno and GetLastError must be separated Windows. > > > > The doc of mktemp mentioned only errno value. Thus GetLastError() value > is > > undetermined in this case. > > I didn't quite understand you. Do you mean the current code for > FFI.errno is wrong? Should it be replaced with _get_errno? > > Or is it simply up to library authors to know which one to use? > > > I think FFI.errno should be errno regardless Linux or Windows and provide another method for GetLastError() something like FFI.get_last_error. Regards, Park Heesob -------------- next part -------------- An HTML attachment was scrubbed... URL: From djberg96 at gmail.com Thu Apr 19 16:54:11 2012 From: djberg96 at gmail.com (Daniel Berger) Date: Thu, 19 Apr 2012 12:54:11 -0400 Subject: [Win32utils-devel] FFI and wide character output buffers Message-ID: Hi all, I've seen how to deal with wide input strings with FFI, but I'm not sure how to deal with output buffers for wide character functions. I tried this: class Windows extend FFI::Library ffi_lib :kernel32 attach_function :GetTempPathA, [:ulong, :pointer], :long attach_function :GetTempPathW, [:ulong, :pointer], :long def self.temp_path buf = 0.chr * 256 buf.encode!("UTF-16LE") ptr = FFI::MemoryPointer.from_string(buf) # segfault or interpreter failure here if GetTempPathW(ptr.size, ptr) == 0 raise SystemCallError, FFI.errno, "GetTempPathW" end p ptr.read_string end end Windows.temp_path Any suggestions? Regards, Dan From djberg96 at gmail.com Thu Apr 19 21:23:34 2012 From: djberg96 at gmail.com (Daniel Berger) Date: Thu, 19 Apr 2012 17:23:34 -0400 Subject: [Win32utils-devel] FFI and wide character output buffers In-Reply-To: References: Message-ID: On Thu, Apr 19, 2012 at 12:54 PM, Daniel Berger wrote: > Hi all, > > I've seen how to deal with wide input strings with FFI, but I'm not > sure how to deal with output buffers for wide character functions. I > tried this: > > class Windows > ?extend FFI::Library > > ?ffi_lib :kernel32 > > ?attach_function :GetTempPathA, [:ulong, :pointer], :long > ?attach_function :GetTempPathW, [:ulong, :pointer], :long > > ?def self.temp_path > ? ?buf = 0.chr * 256 > ? ?buf.encode!("UTF-16LE") > ? ?ptr = FFI::MemoryPointer.from_string(buf) > > ? ?# segfault or interpreter failure here > ? ?if GetTempPathW(ptr.size, ptr) == 0 > ? ? ?raise SystemCallError, FFI.errno, "GetTempPathW" > ? ?end > > ? ?p ptr.read_string > ?end > end > > Windows.temp_path > > Any suggestions? Disregard. Changing the second arg from :pointer to :buffer_out and just using an encoded string worked. Regards, Dan From djberg96 at gmail.com Sat Apr 21 13:15:29 2012 From: djberg96 at gmail.com (Daniel Berger) Date: Sat, 21 Apr 2012 09:15:29 -0400 Subject: [Win32utils-devel] RbConfig and CPPOUTFILE Message-ID: Hi, For some reason with my version of Ruby built with MSVC++ 10 the RbConfig::CONFIG['CPPOUTFILE'] value is set to "-P". Shouldn't it be set to an actual file? With mingw it's set to "-o conftest.i" I guess I was expecting something like "/Fo conftest.i". I ran into this with mkmf-lite if you're curious, since I was using the result of CPPOUTFILE to help create a build command. Or am I misusing this? Regards, Dan From djberg96 at gmail.com Sat Apr 21 14:14:15 2012 From: djberg96 at gmail.com (Daniel Berger) Date: Sat, 21 Apr 2012 10:14:15 -0400 Subject: [Win32utils-devel] RbConfig and CPPOUTFILE In-Reply-To: References: Message-ID: On Sat, Apr 21, 2012 at 9:15 AM, Daniel Berger wrote: > Hi, > > For some reason with my version of Ruby built with MSVC++ 10 the > RbConfig::CONFIG['CPPOUTFILE'] value is set to "-P". Shouldn't it be > set to an actual file? With mingw it's set to "-o conftest.i" > > I guess I was expecting something like "/Fo conftest.i". > > I ran into this with mkmf-lite if you're curious, since I was using > the result of CPPOUTFILE to help create a build command. Or am I > misusing this? Ok, I think I got a bit confused there. MS just defaults to using the input file name + ".i" with the -P option, so I guess it's why it's set like that. Although, now I'm wondering why CPPOUTFILE is creating a .i file for gcc, since that's typically used for preprocessed files and not executables, right? Regards, Dan