Subject:
[ruby-ffi] Using Windows Unicode functions
From:
Quintus
Date:
1/19/10 7:08 AM
To:
ruby-ffi


Hi there,

I'm trying to access Windows functions through the ffi gem, but I
wasn't that successfull (otherwise I wouldn't post here, I
think  ;-)  ). So far, I've been using the win32-api gem which worked
quite well with the Windows Unicode functions (they require UTF-16LE
encoded strings, also known as the wchar_t C type I think), but I
wasn't able to construct that with ffi.

Here's my code so far:
-------------------------------------
#Encoding: UTF-8
require "ffi"

module Test
  extend FFI::Library

  ffi_lib "user32"
  ffi_convention :stdcall

  attach_function :message_box, :MessageBoxW,
[:long, :string, :string, :int], :int
end

module Test2
  extend FFI::Library

  CP_UTF8 = 65001
  MB_PRECOMPOSED = 0x00000001

  ffi_lib "kernel32"
  ffi_convention :stdcall

  attach_function :get_last_error, :GetLastError, [], :long
  attach_function :multi_byte_to_wide_char, :MultiByteToWideChar,
[:uint, :int, :string, :int, :buffer_out, :int], :int
end

buffer = "\0" * 100_000

#I know, I could use Rubys built-in encoding functions
#and I WILL do so, but for now this is to ensure
#everything is 100% correct as MS it expects.
ret = Test2.multi_byte_to_wide_char(Test2::CP_UTF8, 0, "Test",
"Test".length, buffer, buffer.length)

buffer.force_encoding("UTF-16LE")
puts buffer.encode("ISO-8859-1").rstrip #Everything displayed correct

#The following line causes the error:
Test.message_box(0, buffer, buffer, 0)
-------------------------------------


This is the error message:
-------------------------------------
t2.rb:32:in `message_box': string contains null byte (ArgumentError)
  from t2.rb:32:in `<main>'
-------------------------------------
An UTF-16LE encoded string *contains* NUL bytes, I know--but I want to
use Unicode functions, so: How to do that?

My ruby version: ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-
mingw32]
My OS: Windows Vista Home Premium SP2 (32 bit)

Marvin