Search code examples
c#c++unity-game-engineprotocol-buffers

How to solve System.Runtime.CompilerServices.Unsafe FileNotFoundException Google Protobuf? (Using C++ and C#) In Unity


After having changed my C++ code through my previous question, I found myself unable to display the data within Unity. It has a Debug.Log function which should display the 'array' I sent through from C#. Now this issue had evolved into a FileNotFoundException, tying into the currently asked question.

The error is as follows:

FileNotFoundException: Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
Google.Protobuf.CodedInputStream.ReadFloat () (at <817bcbeeba124ec59e5347ee91ea8025>:0)
Sphere.Sphere+Types+Position.MergeFrom (Google.Protobuf.CodedInputStream input) (at Assets/Scripts/Test/Sphere/Sphere.cs:385)
Google.Protobuf.ParsingPrimitivesMessages.ReadRawMessage (Google.Protobuf.ParseContext& ctx, Google.Protobuf.IMessage message) (at <817bcbeeba124ec59e5347ee91ea8025>:0)
Google.Protobuf.ParsingPrimitivesMessages.ReadMessage (Google.Protobuf.ParseContext& ctx, Google.Protobuf.IMessage message) (at <817bcbeeba124ec59e5347ee91ea8025>:0)
Google.Protobuf.CodedInputStream.ReadMessage (Google.Protobuf.IMessage builder) (at <817bcbeeba124ec59e5347ee91ea8025>:0)
Sphere.Sphere.MergeFrom (Google.Protobuf.CodedInputStream input) (at Assets/Scripts/Test/Sphere/Sphere.cs:199)
Google.Protobuf.ParsingPrimitivesMessages.ReadRawMessage (Google.Protobuf.ParseContext& ctx, Google.Protobuf.IMessage message) (at <817bcbeeba124ec59e5347ee91ea8025>:0)
Google.Protobuf.ParsingPrimitivesMessages.ReadMessage (Google.Protobuf.ParseContext& ctx, Google.Protobuf.IMessage message) (at <817bcbeeba124ec59e5347ee91ea8025>:0)
Google.Protobuf.FieldCodec+<>c__DisplayClass32_0`1[T].<ForMessage>b__0 (Google.Protobuf.ParseContext& ctx) (at <817bcbeeba124ec59e5347ee91ea8025>:0)
Google.Protobuf.Collections.RepeatedField`1[T].AddEntriesFrom (Google.Protobuf.ParseContext& ctx, Google.Protobuf.FieldCodec`1[T] codec) (at <817bcbeeba124ec59e5347ee91ea8025>:0)
Google.Protobuf.Collections.RepeatedField`1[T].AddEntriesFrom (Google.Protobuf.CodedInputStream input, Google.Protobuf.FieldCodec`1[T] codec) (at <817bcbeeba124ec59e5347ee91ea8025>:0)
Sphere.Spheres.MergeFrom (Google.Protobuf.CodedInputStream input) (at Assets/Scripts/Test/Sphere/Sphere.cs:704)
Google.Protobuf.MessageExtensions.MergeFrom (Google.Protobuf.IMessage message, System.IO.Stream input, System.Boolean discardUnknownFields, Google.Protobuf.ExtensionRegistry registry) (at <817bcbeeba124ec59e5347ee91ea8025>:0)
Google.Protobuf.MessageParser`1[T].ParseFrom (System.IO.Stream input) (at <817bcbeeba124ec59e5347ee91ea8025>:0)
Sphere_receive.Start () (at Assets/Scripts/Test/Sphere/Sphere_receive.cs:22)

EDITED The corresponding Sphere.cs block appeared to be to big for the body in its entirety, if you want to look at it please ask.

Now my own C# implementation of the original idea looked something like this:

using System.Collections;
using System.IO;
using UnityEngine;
using Sphere;
using Google.Protobuf;
using System.Runtime.CompilerServices;


public class Sphere_receive : MonoBehaviour
{
    private GameObject blockObj1, blockObj2, blockObj3;    
    private Vector3 position1, scale1, position2, scale2, position3, scale3;
    private Spheres sphereCollection;
    private string String;
    
    // Start is called before the first frame update
    void Start()
    {

    using(var input = File.OpenRead("./Assets/Scripts/sphereData.dat"))
    {
        sphereCollection = Spheres.Parser.ParseFrom(input);
    }

 
    Debug.Log(sphereCollection.ToString());

    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

I dont know exactly whether the fact my Debug.Log not showing could be related to the thrown error, or if my implementation is simply wrong.


Solution

  • Okay so, after some very painful experimentation what has appeared to be the proper solution for me here was the following:

    1. I looked up System.Runtime.CompilerServices.Unsafe v4.5.3 on the NuGet Gallery and dowloaded the package. (Version 4.5.3 is also assembly version 4.0.4.1)
    2. Changed the downloaded .nupkg to a .zip (Don't know if it's a relevant step or not though)
    3. Extracted it and located the System.Runtime.CompilerServices.Unsafe.dll file within the lib/netstandard2.0 folder
    4. Dragged this .dll into the project folder

    Seems the solution appeared a lot more simplistic than I had originally foreseen.