Fiddle + áéűúőóüöí = FAIL

I want to load an external library located in a hungarian user space. The path contains letters like áéűúőóüöí.

Fiddle.dlopen(...)

throws the error (Windows 11, Skp22)

Error: #<Fiddle::DLError: No such file or directory>

Does anyone know how to make this work?

Attached below is a dummy so-file (with a txt file ending - .so can not be uploaded) and a code snippet that loads the .so from the relative path

/áéűúőóüöí/SUEX_HelloWorld.txt
module CharTest2000

  begin
    path = File.join(__dir__, "áéűúőóüöí/SUEX_HelloWorld.txt")
    path_encoded = path.force_encoding("UTF-16LE")
    dll_handle = Fiddle.dlopen(path_encoded)
    puts "SUCCESS  "+dll_handle.to_s
  rescue => e
    puts "ERROR: "+e.to_s+" | Encoding:  "+path_encoded.encoding.to_s 
  end
  
end

SUEX_HelloWorld.txt (92 KB)

both of these works for me

path_encoded = path.force_encoding(Encoding::UTF_16LE)
path_encoded = path.force_encoding(Encoding::UTF_8)
1 Like

I would say that the Ruby code is UTF-8, so you should not use #force_encoding.
Instead use #encode

path_encoded = path.encode(Encoding::UTF_16LE)

I am not sure the reason why "UTF-16LE" does not work.

It is not a registered alias for the Encoding class. IE …

Encoding.aliases.key('UTF-16LE').inspect
#=> nil

But it is in the name list …

Encoding.name_list.sort

So it’s some quirk I suppose. Using the constant identifier for the encoding is better anyway.

Is path really consisting of UTF-16 bytes here? What you do here looks to be having some issues:

  • __dir__ might have the wrong encoding due to a Ruby bug. I’d fix that separately. The string should be UTF-8, but with incorrect encoding label. This is why I do this in my extensions:
  • What is the encoding of the file where you have "áéűúőóüöí/SUEX_HelloWorld.txt"? If you have the file saved as UTF-8 and then force the encoding UTF-16 then the bytes will be all wrong.

What I’d do is:

  dir = __dir__
  # Account for Ruby encoding bug under Windows.
  dir.force_encoding('UTF-8') if file.respond_to?(:force_encoding)
  # Now `dir` should be correctly labeled UTF-8 string.

  path = File.join(dir, "áéűúőóüöí/SUEX_HelloWorld.txt")
  # Assuming you saved the file as UTF-8, you should now have a well-formed UTF-8 string.

  # Not sure what encoding Fiddle.dlopen accepts, but if you need UTF-16 you need to convert
  # the encoding, not forcing it.
  path_utf16 = path.encode("UTF-16LE")