1

I am in the process of building a sub-part of a native application, namely a Unity application that runs as a child of a different application written in a completely different language. Since we have to run on mobile devices and we need to share a lot of data between the two parts, we are looking into a way to pass pointers to strings from the wrapper application to the Unity child.

I have however run into a problem when it comes to marshalling, namely that Marshal.PtrToString(Ansi/Auto/Etc) all specify in the documentation that they will copy the content of the IntPtr to a new managed string, which defeats the point.

Our goal is to read the data as a string without creating another copy. It has to be seen as a string at compile time as a library we use only accepts strings as arguments.

Is there any way to do so? Unsafe code is acceptable.

  • Do you also take Character Sets into account here? UTF8/Unicode etc – Jeroen van Langen May 13 '22 at 10:31
  • 3
    You can't turn raw pointers into managed strings without copying -- full stop. (You could round-trip them if string creation is under your control, if you are extremely careful with not overwriting the string intern pool, but not if the pointers are generated on the other side.) You can turn such pointers into `Span` instances and work on those, though, but that may require an extensive retooling. – Jeroen Mostert May 13 '22 at 10:36
  • If you are using P/Invoke to pass a string to a function that's expecting a UTF16 string, you should just be able to pass the string and it will be pinned and blitted by the marshaller. [From this documentation](https://learn.microsoft.com/en-us/dotnet/standard/native-interop/best-practices): "string contains blittable contents if it isn't contained in another type and it's being passed as an argument that is marked with [MarshalAs(UnmanagedType.LPWStr)] or the [DllImport] has CharSet = CharSet.Unicode set." – Matthew Watson May 13 '22 at 10:37
  • 1
    Does this answer your question? [Fastest way to do local IPC between a Unity process and another C# process](https://stackoverflow.com/questions/32632645/fastest-way-to-do-local-ipc-between-a-unity-process-and-another-c-sharp-process). I think your question of marshalling is an XY problem when you really want to focus on _"...we need to share a lot of data between the two parts..."_ requirement. Named pipes, shared memory is pretty **cross-platform**. –  May 13 '22 at 10:44
  • 1
    This sounds like premature optimization to me. Copying small amount of strings should have a negligible performance impact. If you are sharing lots of data you should not represent it as strings. – JonasH May 13 '22 at 10:50
  • Also check out [Object Sharing between Applications?](https://stackoverflow.com/a/28335134/585968) –  May 13 '22 at 10:50
  • JeroenMostert Gonna check if Spans can help MatthewWatson seems promising. MickyD I'll need to see if the other application (developed in React native) supports any of those things, but definitely a possibility. JonasH They're REST response payloads, we need to download and cache them, there is no point in copying them too, as we're on a shoestring budget when it comes to memory. – Giulio Robecchi May 13 '22 at 12:34

0 Answers0