title: Unity cannot build GRPC Project for UWP with IL2CPP Backend
body: <p><a href="https://github.com/jsmouret/grpc-unity-package" rel="nofollow noreferrer">Here</a>, or <a href="https://github.com/grpc/grpc/tree/befc7220cadb963755de86763a04ab6f9dc14200/src/csharp" rel="nofollow noreferrer">here</a> for a complete version, you can find a sample GRPC "Hello World" project for Unity. Only the first version, that is built for Unity and wrapped in a DLL is working perfectly <strong>fine</strong> in Unity IDE and on <strong>Standalone build</strong>. The Raw Grpc.Core files are referencing everything correctly in IDE but they have Marshaling problem.</p>
  
  <p>Unfortunately, it cannot get build for UWP with IL2CPP backend. Unity builds the project and creates a .sln project. But Visual Studio always gives LNK2001 for GRPC properties on the final compilation.</p>
  
  <p>Here are  first error codes:</p>
  
  <pre><code>LNK2001 unresolved external _grpccsharp_init@0
  LNK2001 unresolved external _grpccsharp_shutdonw@0
  LNK2001 unresolved external _grpccsharp_version_string@0
  ...
  </code></pre>
  
  <p>Ok, thanks to @Sunius, I digged into it a little bit more. There are some points, I am going to add to the question:</p>
  
  <p>There are two methods regarding referencing <strong>extern</strong> methods in GRPC C# package. They are named <strong>static</strong> and <strong>shared</strong> libs.</p>
  
  <pre><code>internal class DllImportsFromStaticLib
  {
      private const string ImportName = "__Internal";
  
      [DllImport(ImportName)]
      public static extern void grpcsharp_init();
  
      [DllImport(ImportName)]
      public static extern void grpcsharp_shutdown();
  
      ...
  }
  </code></pre>
  
  <p>and</p>
  
  <pre><code>internal class DllImportsFromSharedLib
  {
      private const string ImportName = "grpc_csharp_ext";
  
      [DllImport(ImportName)]
      public static extern void grpcsharp_init();
  
      [DllImport(ImportName)]
      public static extern void grpcsharp_shutdown();
  
      ...
  }
  </code></pre>
  
  <p>I tried to test it with the shared one, I got another linking error file which is a little bit different.</p>
  
  <pre><code>LNK2001 unresolved external _dlopen@8
  LNK2001 unresolved external _dlsym@8
  ...
  </code></pre>
  
  <p>In two separate methods, extern methods are getting connected to the internal interface:</p>
  
  <pre><code>public NativeMethods(DllImportsFromStaticLib unusedInstance) 
  {
      this.grpccsharp_init = DllImportsFromStaticLib.grpccsharp_init; 
      this.grpccsharp_shutdown = DllImportsFromStaticLib.grpccsharp_shutdonw;
      ...
  }
  </code></pre>
  
  <p>and </p>
  
  <pre><code>public NativeMethods(DllImportsFromSharedLib unusedInstance) 
  {
      this.grpccsharp_init = DllImportsFromSharedLib.grpccsharp_init; 
      this.grpccsharp_shutdown = DllImportsFromSharedLib.grpccsharp_shutdonw;
      ...
  }
  </code></pre>
  
  <p>And which method will get called is defined here:</p>
  
  <pre><code>private static NativMethods LoadNativeMethodsUnity()
  {
      switch(PlatformApis.GetUnityRuntimePlatform())
      {
          case "IPhonePlayer":
              return new NativeMethods(new NativeMethods.DllImportsFromStaticLib());
          default:
              return new NativeMethods(new NativeMethods.DllImportsFromSharedLib());  
      }
  }
  </code></pre>
  
  <p>Some updates:</p>
  
  <p>Thanks to @jsmouret, there is Stub.c file in <a href="https://github.com/jsmouret/grpc-unity-package/issues/6" rel="nofollow noreferrer">his Grpc Github</a> with fake methods, so Linker does not complain about Grpc_init methods anymore.</p>
  
  <p>Next Error: dlopen, dlsym, dlerror:</p>
  
  <p>First, I tried to use the same, Stub technique, but it did not help in this case, or maybe I did it wrong.</p>
  
  <p>Thanks to @Sunius, I commented out all of "__Internal" dll import codes. So I am not getting any dlopen, dlsym, and dlerror errors.</p>
  
  <p>Next Error: It happens from inside application, not the visual studio debugger. It tells me: "<strong>exception: to marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition.</strong>"</p>
  
  <pre><code>exception: error loading the embedded resource "Grpc.Core.roots.pem"
  </code></pre>
  
  <p>and </p>
  
  <pre><code>exception: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition.
  </code></pre>
  
  <p>After I googled it, I know my options, but the question it, for which method should I do that?!</p>