我有一个使用.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。它仍然应该为您提供更多背景信息。)