Unity-DirectInput icon indicating copy to clipboard operation
Unity-DirectInput copied to clipboard

Error strings not passed through

Open Risto-Paasivirta opened this issue 2 years ago • 3 comments

Error codes from the DLL plugin does not pass through.

Unable to get error code string from System -> System.ExecutionEngineException: String conversion error: Illegal byte sequence encounted in the input. at (wrapper managed-to-native) System.Runtime.InteropServices.Marshal.PtrToStringAnsi(intptr)

Risto-Paasivirta avatar Dec 04 '23 08:12 Risto-Paasivirta

Hey, Could you add a little more information about your setup? What device are you trying to use? It would be great if you could provide a snippet of the offending code too.

MrTimcakes avatar Dec 04 '23 11:12 MrTimcakes

Actually I think we managed to find out why. It's probably because you are using the string sRet = Marshal.PtrToStringAnsi(lpMsgBuf); In the GetSystemMessage(int errorCode)

Which works fine on English devices but break if there are special characters like in case of our machines which some of them were in Finnish localization.

Windows messages should always be treated as UTF encoded I believe (they have been moving from ANSI to UTF over time and I think most if not all is now UTF). This has been quite invisible for English users since ANSI==UTF when dealing with only English alphabet.

We are still testing and I will keep you informed on how it goes, I think you can test and break the system if you switch localization some European language with umlaut characters (we have ä and ö in Finnish).

We are running on Windows Home and Pro 64-bit, nothing special. My dev machine was doing fine (I have US-EN localization on this computer, but many of our target machines are Finnish).

Risto-Paasivirta avatar Dec 05 '23 10:12 Risto-Paasivirta

One more update:

So running as a test GetSystemMessage(2) will cause the problem (error code 1 does not contain special characters in Finnish so it works).

For the error code 2 The Finnish error would be "Määritettyä tiedostoa ei löydy." = "The system cannot find the file specified."

If using the Marshal.PtrToStringAnsi(lpMsgBuf) method it won't work because of the ä and ö characters.

I noticed that just changing it to Marshal.PtrToStringUTF8(lpMsgBuf) won't work either, because the Unity managed-to-native wrapper will try to internally call the Ansi method still so the problem persists.

However making a method to do the conversion is quite easy so I added a function

private static string PtrToStringUTF8(IntPtr ptr)
        {
            int len = 0;
            while (Marshal.ReadByte(ptr, len) != 0) ++len;
            if (len == 0) return "";
            byte[] array = new byte[len];
            Marshal.Copy(ptr, array, 0, len);
            return Encoding.UTF8.GetString(array);
        }

that I use to convert it and it works. Unity won't still show the ä and ö properly, but that is because of the font asset. At least the string gets through without issues using that.

I hope this helps.

Risto-Paasivirta avatar Dec 05 '23 10:12 Risto-Paasivirta