I read somewhere that using unsafe code comes along with some limitations regarding the game portability but I’m searching now and just can’t find enough texts about this topic.
My project relies on some platform invoke and I rather use some unsafe contexts and pointers here and there (nothing critical, just to ease the development) than marshalling data structures. However I’m afraid that this can limit the platforms I can build my game on (I’m planning to build the game to several platforms).
Is there any literature on the subject I can read?
Should I use C# marshalling rather than unsafe and pointers?
I’m not sure about the possible limitations. As far as I know, there are none, the safe/unsafe thing is really just a “safety” ruling to enforce coding practices within an organization (due to constraints of scalability, cross-platformness, 3rd-party dependancy, or just style). But when you’re making a game with Unity, there is only cross-platformness to think of, and I’m not sure why things wouldn’t work. Sure, they might end up running slower on some devices, than what you intended, for some reason, but it shouldn’t fail to compile. But that’s just what I think, I have zero proof, and maybe I’m wrong.
Well, in the past Unity had limitations for iOS builds as well as WebPlayer builds. Though since the WebPlayer is a thing from the past I don’t think there’s much of an issue. Unsafe code makes any automatic security validation impossible. I do not publish for iOS, though Apple still has strict code reviews. I don’t know how they handle submits with unsafe code now. One big issue with unsafe code is that it potentially allows self modifying code which is next to impossible to review / analyse.
Unsafe does not allow self-modifying code. All it does is allow C/C++ style direct manipulation of pointers and memory that bypasses the dotnet managed features, which mean absolutely nothing for any platform since C# is not a first-class language anywhere.
For several years already the only way to publish to iOS from Unity has been via IL2CPP, which converts your entire code to C++ before building, which allow you to do any “dangerous” things you could do with unsafe C#.
So yes, there’s no problem in using unsafe. As a matter of fact, many Unity packages actually use it. The native collections package, for example, makes heavy use of unsafe code.
unsafe does technically allow self-modifying code. I don’t believe you can modify code memory via ordinary pointer means, but I know for a fact its possible via OS calls such as NtWriteVirtualMemory.
Right, technically you don’t even need unsafe code for self modifying code since PInvoke is enough. The actual native method btw is WriteProcessMemory which is a kernel function. I’m pretty sure NtWriteVirtualMemory is just a wrapper around this one.
Anyways my main point was security validation and that it’s much easier to shoot yourself in the foot if you’re not careful.
You cannot execute code from any memory that is data, while you can write to virtual memory that is not enough. You need to mark the memory pages with PAGE_EXECUTE during allocation with virtualalloc.
This is also the reason that unsafe code is safe in that it wont allow you to magically bypass all measures to execute code from data and its only since windows xp that this became supported in support of jit compilers. Before that you had to be a driver in kernel mode.