4 ms·
There are quirks here and there; I use mono through unity3d, so that informs the things I notice. Specifically interop with unmanaged DLLs is: well, more guessw
by barrettcolin 16y ago
There are quirks here and there; I use mono through unity3d, so that informs the things I notice. Specifically interop with unmanaged DLLs is: well, more guesswork than I would like. For instance, Marshal.PtrToStringAnsi (function that creates a .NET string from an unmanaged char* pointer) expects UTF-8 data; best of luck deducing that from the name of the function or the documentation.
- barrkel 16y agoAnsi strings in Windows are encoded using the current codepage, which is an OS-level setting depending on the localization settings. Most of the time, in the Western world, it's Windows-1252 Western European / Latin-1. It indicates how string arguments to the Ansi versions of WinAPI functions will be interpreted (ending in A rather than W). This is the way things have been done on Windows for ages, so I don't think the concept is particularly foreign to people expert enough to need interop with native libraries. The Mono documentation[1] indicates that Mono uses UTF-8 for all string marhsalling operations, which seems pretty unambiguously documented. It's as if GetACP() returned CP_UTF8. [1] http://www.mono-project.com/Interop_with_Native_Libraries http://www.mono-project.com/Interop_with_Native_Libraries
- barrettcolin 16y agoRight, understood. My particular beef was that the function to create a managed Mono string from a UTF-8 encoded unmanaged string was Marshal.PtrToStringAnsi (which is even more confusing if you are familiar with the Windows string encoding heritage: how should the data be encoded in Mono on Windows? Still as UTF-8, I think counter-intuitively, and differently to Microsoft's own runtime, which will of course expect ANSI). Let me also get a dig in at the documentation of the function: http://www.go-mono.com/docs/index.aspx?link=M:System.Runtime.InteropServices.Marshal.PtrToStringAnsi http://www.go-mono.com/docs/index.aspx?link=M:System.Runtime...
- migueldeicaza 16y agoThe problem is simple, this is a design mistake in .NET's API. They designed the Marshal class to suit Windows and Windows only and they only had two choices UCS2/UTF16 encoding which they call "Unicode" and current code page which they call "ANSI". Adding a new API say PtrFromUtf8 would mean that the code would not run on Windows because all of a sudden we are referencing a method that does not exist on .NET. So we took the approach of turning "current code page" in Unix to what made sense on Unix: it is UTF8. In fact, the particular issue of UTF-8 encoding is the oldest bug opened against Mono, not something that we can fix without breaking binary compatibility. At this point, we value more staying binary compatible with the core libraries than breaking compatibility with the .NET toolchain. We try to extend Mono in /new/ libraries like Mono.Simd or Mono.Unix where we have complete reign over the API and can still let them run on Windows with the native .NET toolchain.
- barrettcolin 16y agoWhether it was a mistake is rather a matter of perspective: I'm sure the Microsoft folks didn't think it was wrong. But that aside: I realize that it may not have read that way, but I think what Mono does is an elegant solution to an unfortunate problem so I'm not knocking the approach. For something so fundamental (and obtuse), I just found that it was skirted a little too broadly in the docs that I read (I also searched around mailing lists for a while, where this particular topic seems to have been an intermittent source of confusion over the years). Nonetheless, thank you for taking the time to address my observation.