[Win32utils-devel] Using callbacks with ReadFileEx
Berger, Daniel
Daniel.Berger at qwest.com
Tue Sep 25 09:29:48 EDT 2007
Hi all,
First, I just realized I'll need to go back and fix some of the
prototype declarations for windows-pr. The callback parameters will now
need to be set to 'K'. ReadFileEx is one example of this. For purposes
of my question, let's assume ReadFileEx has been declared like so:
API.new('ReadFileEx', 'LPLPK', 'B')
Now that we have callback support in win32-api, I thought I'd give
asynchronous IO a shot. Problem is, I'm not sure how to do it in this
case. What I would like is for the user to be able to provide a block,
and have that block called once the read is finished. Here's what I've
tried so far:
require 'windows/file'
require 'windows/handle'
require 'windows/error'
require 'windows/synchronize'
require 'win32/event'
module Windows
module NIO
include Windows::File
include Windows::Handle
include Windows::Error
include Windows::Synchronize
extend Windows::File
extend Windows::Handle
extend Windows::Error
extend Windows::Synchronize
class Error < StandardError; end
def self.read_async(file, length=nil, offset=0, &block)
handle = CreateFile(
file,
FILE_READ_DATA,
FILE_SHARE_READ,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
0
)
if handle == INVALID_HANDLE_VALUE
raise Error, get_last_error
end
func = Win32::API::Callback.new('LLP', 'V'){
block.call
}
overlapped = 0.chr * 20
if offset > 0
overlapped[8,4] = [offset].pack('L') # OVERLAPPED.Offset
end
# Ruby's File.size fails for files over 2gb
unless length
size = [0].pack('Q')
GetFileSizeEx(handle, size)
length = size.unpack('Q').first
end
buf = 0.chr * length
bool = ReadFileEx(
handle,
buf,
length,
overlapped,
func
)
unless bool
err = get_last_error()
CloseHandle(handle)
raise Error, err
end
CloseHandle(handle)
buf[0,length]
end
end
end
if $0 == __FILE__
include Win32
file = 'test.txt'
data = NIO.read_async(file){ puts "Hello" }
p data
end
When I run this, however, I get this error:
C:/ruby/lib/ruby/site_ruby/1.8/windows/error.rb:329:in `call': wrong
number of parameters: expected 1, got 0 (ArgumentEr
ror)
from C:/ruby/lib/ruby/site_ruby/1.8/windows/error.rb:329:in
`get_last_error'
from nio.rb:124:in `read_async'
from nio.rb:140
What am I doing wrong here?
Thanks,
Dan
This communication is the property of Qwest and may contain confidential or
privileged information. Unauthorized use of this communication is strictly
prohibited and may be unlawful. If you have received this communication
in error, please immediately notify the sender by reply e-mail and destroy
all copies of the communication and any attachments.
More information about the win32utils-devel
mailing list