Reputation: 105
I am trying to use a C# library in my .net Core 5.0 project, which is a C# wrapper for a C Assembly for ws281x LEDs. The library requires the that the Shared C library (ws2811.so) be built before running the framework. I have successfully built and installed the C shared library into /usr/lib for my raspberry pi, and have tested it to confirm it works.
The issue lies in that within my Dockerfile, I don't know how/where to properly install this shared C library. My current dockerfile is as follows:
# https://hub.docker.com/_/microsoft-dotnet
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /source
COPY ./ /source
# installs NodeJS and NPM
RUN apt-get update -yq && apt-get upgrade -yq && apt-get install -yq curl git nano
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - && apt-get install -yq nodejs build-essential
RUN npm install -g npm
RUN npm --version
# installing c wrapper for ws2811 -- Here is where I need HELP
RUN apt-get update && apt-get install -y python
RUN apt-get install -y python-setuptools python-dev build-essential python-pip
RUN pip install scons && git clone https://github.com/jgarff/rpi_ws281x.git \
&& cd rpi_ws281x && scons && gcc -shared -o ws2811.so *.o
# copy csproj and restore as distinct layers
COPY *.sln .
COPY control/ *.csproj ./control/
RUN dotnet restore -r linux-arm
# copy everything else and build app
COPY control/. ./control/
WORKDIR /source/control
RUN dotnet publish -c release -o /app -r linux-arm --self-contained false --no-restore
# final stage/image
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim-arm32v7
WORKDIR /app
COPY --from=build /app ./
ENTRYPOINT ["./control"]
As it is now, the dockerfile builds correctly and the app launches. However, when I try to use a method to invoke the ws2811.so library through P/Invoke, I get the following error:
System.DllNotFoundException: Unable to load shared library 'ws2811.so' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libws2811.so: cannot open shared object file: No such file or directory
Which is telling me that P/Invoke is unsuccessful in finding the ws2811.so library. Where should I put this ws2811.so library so that my C# code can access it? I've tried placing it with the source code, I've played around with installing it in docker, but am really at a standstill and don't know where to go from here.
For a bit more information, the C# code to invoke this C-shared library is as follows. It is essentially the same thing as done in the example on the ws281x GitHub (as linked earlier).
public void setRgb()
{
Console.WriteLine("R: " + r + "\tG: " + g + "\tB: " + b);
var settings = Settings.CreateDefaultSettings(false);
var controller = settings.AddController(88, Pin.Gpio18, StripType.WS2812_STRIP, 255, false);
Color color = new Color();
color = Color.FromArgb(r, g, b);
using (var rpi = new WS281x(settings)) // EXCEPTION OCCURS HERE (System.DllNotFound)
{
rpi.SetLedCount(88);
rpi.SetAll(color);
}
}
Any help, guidance, or resources are extremely appreciated! Thanks so much :)
Upvotes: 0
Views: 2997
Reputation: 3965
Docker has the concept of a "build context". That defines the directory from which files are accessed. So when you say COPY foo /foo
in your Dockerfile, that's copying the foo
file from the build context and places it in the root folder of your container with the name foo
. You set the build context when running the docker build
command. Very often, people use .
as the build context which means the current working directory that you're running the command from (e.g. docker build -t app .
). So it depends on what directory your build context is. That's where you should be placing the .SO library so that you can then add a COPY
instruction in your Dockerfile to copy it into your container image.
Upvotes: 2