在AWS Lambda上使用System.Drawing.Common NuGet包时无法加载DLL"libdl"

Joh*_*ica 14 c# aws-lambda .net-core-2.0

我有一个缩略图生成器lambda函数,我正在尝试更新到.NET Core 2.0,但是在使用Microsoft的System.Drawing.CommonNuGet包时遇到以下错误:

TypeInitializationException

'Gdip'的类型初始化程序引发了异常.在TestFailExample的System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32宽度,Int32高度,Int32步长,Int32格式,HandleRef scan0,IntPtr和位图)处于System.Drawing.Bitmap..ctor(Int32宽度,Int32高度,PixelFormat格式)处.Function.FunctionHandler(String输入,ILambdaContext上下文)在C:\ work\graphics\TestFailExample\Function.cs:第25行在lambda_method(Closure,Stream,Stream,LambdaContextInternal)

引起的

DllNotFoundException

无法加载DLL'libdl':找不到指定的模块或其中一个依赖项.\n(来自HRESULT的异常:0x8007007E),位于System.Drawing.SafeNativeMethods的Interop.Libdl.dlopen(String fileName,Int32标志). System.Drawing.SafeNativeMethods.Gdip..cctor()中的Gdip.LoadNativeLibrary()

我已经看到了这个问题,但没有解决方案.

重现问题的最小代码是:

public string FunctionHandler(string input, ILambdaContext context)
{
    using (var bmp = new Bitmap(100, 100))
    {
        return bmp.Width.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

只需创建一个.NET Core 2.0 Lambda函数项目,添加对System.Drawing.CommonNuGet包的引用,并用上面的代码替换函数处理程序.将其放在AWS上并运行它以获取错误.我已经注意到,在您尝试实际使用它之前,引用该包不会导致问题,但这可能归结为编译器优化.

我已经将MCVE打包到一个项目中并将其上传到GitHub ,以简化人们为重现问题而必须完成的步骤.

我可以看到/lib64/libdl.so.2存在,但/lib64/libdl.so没有.由于符号链接似乎不可能(只读文件系统),我不知道如何解决这个问题.我尝试使用LD_LIBRARY_PATH环境变量,通过创建一个文件夹/tmp并将文件符号链接到那里作为函数的第一件事.不幸的是,它似乎在这里查找所有库,因此该函数根本不运行.我也试着设置LD_LIBRARY_PATH/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/tmp,虽然我现在可以再次运行该功能,这仍然没有帮助,我只是得到相同的Gdip错误.

我注意到/ var/task/lib已经包含在LD_LIBRARY_PATH中,所以我尝试用我的函数打包libdl.so和libgdiplus.so,但这也失败了,这次说明GdiplusStartup找不到入口点libdgiplus.so.这些文件不是来自Amazon Linux实例,因此我现在尝试安装Mono并从Amazon Linux实例获取它们.这没有帮助.

我已经尝试过使用CoreCompat 绘图库,但是这也报告了与之相关的问题libgdiplus.so,即使我尝试将其与函数捆绑在一起.

我已经在我自己的Linux实例上尝试过并且可以确认它是System.Drawing.Common有效的.

是否有一些聪明的解决方案可以让我System.Drawing.Common在AWS Lambda 上使用?还有另一种方法可以捏造我的lambda函数来拥有libdl并工作吗?

小智 6

在运行 dotnet core 2.1.500 版本的 Ubuntu 18 服务器上上传应用程序后,我遇到了同样的问题。我使用 MichaelSimons 的建议通过此解决方案https://github.com/dotnet/dotnet-docker/issues/618解决了这个问题。

我跑了

#sudo apt-get update
#sudo apt-get install -y --allow-unauthenticated \
        libc6-dev \
        libgdiplus \
        libx11-dev \ 
#sudo rm -rf /var/lib/apt/lists/*
Run Code Online (Sandbox Code Playgroud)

这解决了问题。


小智 -1

对于 .NET Core Lambda 中的图像处理,我使用SixLabors.ImageSharp

以下是我在最近的 AWS re:Invent 演讲中使用的代码,该代码执行了图像处理日志:

var imageBuffer = new MemoryStream();

var resizeOptions = new ResizeOptions
{
    Size = new SixLabors.Primitives.Size { Width = this.TileSize, Height = this.TileSize},
    Mode = ResizeMode.Stretch
};
image.Mutate(x => x.Resize(resizeOptions));
image.Save(imageBuffer, new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder());

imageBuffer.Position = 0;
Run Code Online (Sandbox Code Playgroud)

  • 如果你不能解决他们的问题,你就不能只是告诉他们尝试完全不同的范例。他问如何让 System.Drawing.Common 在 AWS Lambda 上工作 - 你甚至没有尝试回答这个问题。 (6认同)