I’m having trouble passing UTF-8 paths to the Win32API. I am using LoadLibrary to load a DLL using Ruby. This is what I have:
loadLibrary = Win32API.new(“kernel32”, “LoadLibrary”, [‘P’], ‘L’)
result = loadLibrary.Call(dest_path)
if result == 0
UI.messagebox(LH[“Failed to load dll from #{dest_path}”])
raise “Failed to load DLL”
end
My problem is that if dest_path includes multi-byte UTF-8 characters, the call to LoadLibrary will fail.
I have also tried to solve this by using LoadLibraryW, which I believe is for handling wide multi-byte character paths but have not had success yet.
I have also tried to force the Ruby encoding of ‘dest_path’ to Encoding::Windows_1252 and Encoding::UTF_16 but it did not work. Perhaps I did something wrong or am missing a step.
Win32API is a rather old module in Ruby. My impression is that Fiddle is better maintained. (And it works on mac and linux - in terms of calling libraries)
Here is an example of Fiddle calling both the A and W version of MessageBox:
# Load importer part of fiddle (ffi) library
require 'fiddle/import'
# Create module as body for an importer instance
module MessageBox
# Extend this module to an importer
extend Fiddle::Importer
# Load 'user32' dynamic library into this importer
dlload 'user32'
# Set C aliases to this importer for further understanding of function signatures
typealias 'HANDLE', 'void*'
typealias 'HWND', 'HANDLE'
typealias 'LPCSTR', 'const char*'
typealias 'LPCWSTR', 'const wchar_t*'
typealias 'UINT', 'unsigned int'
# Import C functions from loaded libraries and set them as module functions
extern 'int MessageBoxA(HWND, LPCSTR, LPCSTR, UINT)'
extern 'int MessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT)'
end
# Tests
MessageBox::MessageBoxA nil, "Hello world!の", "Fiddle ANSI", 0
MessageBox::MessageBoxW nil, "Hello world!の".encode("utf-16le"), "Fiddle WIDECHAR".encode("utf-16le"), 0
Glad that helped. I was about 99% sure that was the issue, but I didn’t test it.
@tt_su mentioned that Win32API is old (and sort of deprecated), but the most recent Ruby stdlib uses it. For Windows, it works, will probably continue to work, etc…