我有一个使用.NET Core和C#开发的项目,该项目在Docker上运行,必须在用C++开发的DLL上调用一些函数。
问题是:当我在不使用Docker的情况下运行项目时,使用Visual Code在Windows上运行时,代码运行平稳,但是当我在Docker的Linux容器上运行时,在尝试执行DLL函数时,代码会引发错误。

我已经尝试将.dll文件复制到/ lib文件夹,将其更改为项目的父文件夹,但没有一个起作用。我开始怀疑问题是找不到该文件,并且通过做一些研究,我发现它可能与文件权限有关,因此我在.dll文件上运行chmod a + wrx,也没有成功。

这是我的Dockerfile配置:

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
WORKDIR /app
EXPOSE 80
RUN apt-get update \
    && apt-get install -y --allow-unauthenticated \
        libc6-dev \
        libgdiplus \
        libx11-dev \
     && rm -rf /var/lib/apt/lists/*
RUN apt-get update \
    && apt-get install -y poppler-utils

FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app
COPY . .
RUN dotnet restore --configfile Nuget.config -nowarn:msb3202,nu1503
RUN dotnet publish -c Release -o ./out

FROM base AS final
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "MdeGateway.dll"]

这是尝试访问DLL函数的代码:
[DllImport("MyDll.dll")]
private static extern int dllfunction(Int32 argc, IntPtr[] argv);

public static void CallDll(string[] args)
{
    IntPtr[] argv = ArrayToArgs(args);
    dllfunction(args.Length, argv);

    FreeMemory(args, argv);
}

当行'dllfunction(args.Length,argv);'时发生错误被执行。

确切的消息是:

“无法加载共享库'MyDll.dll'或其依赖项之一。为了帮助诊断加载问题,请考虑设置LD_DEBUG环境变量:libMyDll.dll:无法打开共享库文件:没有这样的文件或目录”

另外,如果有人可以教我如何设置LD_DEBUG环境变量,我将不胜感激。

最佳答案



如果我没有看错,那么您有一个C++应用程序,已将其编译为.dll(在Windows上)。您可以在Windows上对此DllImport进行.dll,但在Linux(容器)上则不能。那正确吗?

您是否知道将C++代码编译为.dll(共享库)是Windows特定的东西?非托管代码是特定于体系结构和平台的。在x64上编译的不受管理的.dll不会在arm64上运行。在Windows上编译的不受管理的.dll不会在Linux上运行。

Linux(以及Linux容器,例如docker中的Linux容器)不能使用从Windows上的非托管代码构建的.dll。 Linux需要将非托管(C++)代码编译到共享库(.so文件)中,以便DllImport(以及底层的dlopen调用)在Linux上工作。理想情况下,它将在其中运行容器的平台上运行。

单声道文档涵盖了DllImport的(一个特定)实现,并提供了更多有关linuxt如何工作的背景信息:

https://www.mono-project.com/docs/advanced/pinvoke/

(但是请记住,Mono!= .NET Core。它仍然应该为您提供更多背景信息。)

10-04 10:54
查看更多