【发布时间】:2021-06-12 02:04:45
【问题描述】:
我正在尝试在我的 .net Core 5.0 项目中使用 C# 库,它是 C Assembly for ws281x LED 的 C# 包装器。该库要求在运行框架之前构建Shared C library (ws2811.so)。我已经为我的树莓派成功构建并安装了 C 共享库到 /usr/lib 中,并对其进行了测试以确认它可以正常工作。
问题在于在我的 Dockerfile 中,我不知道如何/在哪里正确安装此共享 C 库。我目前的dockerfile如下:
# 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"]
就像现在一样,dockerfile 正确构建并且应用程序启动。但是,当我尝试使用方法通过 P/Invoke 调用 ws2811.so 库时,出现以下错误:
System.DllNotFoundException: 无法加载共享库“ws2811.so”或其依赖项之一。为了帮助诊断加载问题,请考虑设置 LD_DEBUG 环境变量:libws2811.so: cannot open shared object file: No such file or directory
这告诉我 P/Invoke 未能成功找到 ws2811.so 库。我应该把这个 ws2811.so 库放在哪里,以便我的 C# 代码可以访问它?我已经尝试将它与源代码一起放置,我已经在 docker 中安装它,但我真的处于停滞状态,不知道从哪里开始。
有关更多信息,调用此 C 共享库的 C# 代码如下。它基本上与 ws281x GitHub 上的示例中所做的相同(如前所述)。
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);
}
}
非常感谢任何帮助、指导或资源!非常感谢:)
【问题讨论】:
-
第一条评论:共享库是否存在于您的最终容器映像中? (您正在使用多阶段构建,其中每个容器可能包含也可能不包含来自前一个容器的位)。其次,对于可能的位置,您可以将其放在与应用程序dll相同的位置;
DllImport可以/应该从当前工作目录中获取共享库。 -
我在 Docker 上是个菜鸟,这实际上就是我想要做的,将共享库放入最终的容器映像中。我使用 scons 和 GCC 构建它,但我不确定如何将它包含在图像中。我该怎么做呢?另外——我会尝试将它放在当前工作目录中并回复您。非常感谢。
-
您只是将已发布的应用程序复制到最终的 docker 映像
COPY --from=build /app ./并且该源目录没有您的 SO,因为 dotnet publish 不会把它放在那里。您需要将最终位复制到最后一个阶段 -
这对我来说很有意义,我只是不知道如何将 ws2811.so 实际复制到最终的 docker 映像中。当我尝试将 ws2811.so 复制到 ./ 时,我收到一条错误消息,告诉我 ws2811.so 无处可寻。如何从我的构建文件夹 (/rpi_ws281x) 中获取 .so 文件并将其放入最终暂存区?
标签: c# docker .net-core raspberry-pi dockerfile