20

I have created a very simple program which should list the topics available in a Google Cloud project. The code is trivial:

using System;
using Google.Pubsub.V1;

public class Test
{
    static void Main()
    {
        var projectId = "(fill in project ID here...)";
        var projectName = PublisherClient.FormatProjectName(projectId);
        var client = PublisherClient.Create();
        foreach (var topic in client.ListTopics(projectName))
        {
            Console.WriteLine(topic.Name);
        }
    }    
}

When I run this from a "regular" msbuild project targeting .NET 4.5, it works fine. When I try to use dotnet cli (1.0.0-preview2-003121) with the following project.json file:

{
  "buildOptions": {
    "emitEntryPoint": true
  },
  "dependencies": {
    "Google.Pubsub.V1": "1.0.0-beta01"
  },
  "frameworks": {
    "net45": { }
  }
}

... I see an exception:

Unhandled Exception: System.IO.FileNotFoundException: Error loading native library.
Not found in any of the possible locations c:\[...]\Pubsub.Demo\bin\Debug\net45\win7-x64\nativelibs\windows_x64\grpc_csharp_ext.dll
   at Grpc.Core.Internal.UnmanagedLibrary.FirstValidLibraryPath(String[] libraryPathAlternatives)
   at Grpc.Core.Internal.UnmanagedLibrary..ctor(String[] libraryPathAlternatives)
   at ...

I'm not trying to target .NET Core, so shouldn't this be supported?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    (As a quick side-note, my main reason for asking this question was to create the `google-cloud-dotnet` tag, as a central tag for our Google Cloud .NET client library customers. But I expect this is something that may well come up naturally anyway...) – Jon Skeet Jul 13 '16 at 10:35

1 Answers1

15

This is currently a limitation in gRPC 0.15, which Google.Pubsub.V1 uses as its RPC transport. Under msbuild, the build/net45/Grpc.Core.targets file in the Grpc.Core package copies all the native binaries into place. Under DNX, the packages weren't copied and gRPC tries to look for the file in the right place with the local package repository. Under dotnet cli, we need to use the "runtimes" root directory in the package to host the libraries.

We've implemented a fix for this in gRPC, but we didn't manage to get it into the beta-01 release. We're hoping to fix it for beta-02.

It's possible to work around this by just manually copying the file:

mkdir bin\Debug\net45\win7-x64\nativelibs\windows_x64
copy \users\jon\.dnx\packages\Grpc.Core\0.15.0\build\native\bin\windows_x64\grpc_csharp_ext.dll bin\Debug\net45\win7-x64\nativelibs\windows_x64

... but that's obviously pretty fiddly. I'd suggest just using msbuild until the underlying issue has been fixed.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I guess for `dotnet` if the package structure was changed a little bit then the correct libraries would be copied during dotnet publish and LoadLibrary/DllImport should pick them up as per the search order. I wrote a blog post for RC1 https://blog.3d-logic.com/2015/11/10/using-native-libraries-in-asp-net-5/ and while loading native dependencies now works differently if the package structure described in this post is used things should work. – Pawel Jul 13 '16 at 23:35
  • 1
    @Pawel: I've managed to get it working locally... I just need to tidy it up. – Jon Skeet Jul 14 '16 at 05:01
  • @Jon Skeet.. how to do your workaround. can you please eloborate in detail – Sujatha May 18 '18 at 13:41
  • @Sujatha: This answer is very old; the workaround shouldn't be needed now. If you're still having a problem, please ask a new question. – Jon Skeet May 18 '18 at 14:43