Unicode Literals in WindowsPosted: July 19, 2012
While coding up the BCrypt interop API, there were a lot of unicode string literals in the Windows header. They look like this:
-- DeriveKey KDF Types BCRYPT_KDF_HASH = L"HASH"; BCRYPT_KDF_HMAC = L"HMAC"; BCRYPT_KDF_TLS_PRF = L"TLS_PRF"; BCRYPT_KDF_SP80056A_CONCAT = L"SP800_56A_CONCAT";
In Windows programming, a Unicode literal is expressed in this way. It’s a compiler thing, where the compiler will see the ‘L’ and know that what follows is a unicode literal.
Well, I want the same thing to happen in Lua, but the Lua compiler doesn’t know anything about expressing Unicode string literals. But, it is very flexible, so how about it?
First, the MultiByteToWideChar() function will turn an ascii string into a unicode string, when fed the right parameters. Given a little wrapper, this becomes an easy function to call in Lua:
local function AnsiToUnicode16(in_Src) local nsrcBytes = #in_Src -- find out how many characters needed local charsneeded = kernel32.MultiByteToWideChar(CP_ACP, 0, in_Src, nsrcBytes, nil, 0); if charsneeded < 0 then return nil; end local buff = ffi.new("uint16_t[?]", charsneeded+1) local charswritten = kernel32.MultiByteToWideChar(CP_ACP, 0, in_Src, nsrcBytes, buff, charsneeded) buff[charswritten] = 0 return ffi.string(buff, (charswritten*2)+1); end
So, with this in hand, it’s pretty easy to do this:
local BCRYPT_KDF_HASH = AnsiToUnicode16("HASH");
Here’s where Lua’s flexibility and little quirks make things a bit easier. First of call, it’s pretty easy to alias a function with another name.
local L = AnsiToUnicode16 local BCRYPT_KDF_HASH = L("HASH");
Second, as it turns out, if the function has a single string parameter, you can just drop the ‘(‘, and just use the ” on its own. These two combined give you this:
local L = AnsiToUnicode16 local BCRYPT_KDF_HASH = L"HASH";
And there you have it! Now, whenever you’re calling one of those “…W()” functions within Windows, you can just use this little mechanism, and you’re all set.
And who said Lua doesn’t do Unicode?