在AWS Lambda上使用System.Drawing.Common NuGet程序包时无法加载DLL'libdl' [英] Unable to load DLL 'libdl' when using System.Drawing.Common NuGet package on AWS Lambda

查看:143
本文介绍了在AWS Lambda上使用System.Drawing.Common NuGet程序包时无法加载DLL'libdl'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We have a thumbnail generator lambda function which I'm trying to update to .NET Core 2.0, but I've encountered the following error when using Microsoft's System.Drawing.Common NuGet package:

TypeInitializationException

TypeInitializationException

"Gdip"的类型初始值设定项引发了异常. 在System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32宽度,Int32高度,Int32跨度,Int32格式,HandleRef scan0,IntPtr和位图)处 在System.Drawing.Bitmap..ctor处(Int32宽度,Int32高度,PixelFormat格式) 在C:\ work \ graphics \ TestFailExample \ Function.cs:line 25中的TestFailExample.Function.FunctionHandler(String input,ILambdaContext context)中 在lambda_method(Closure,Stream,Stream,LambdaContextInternal)

The type initializer for 'Gdip' threw an exception. at System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32 width, Int32 height, Int32 stride, Int32 format, HandleRef scan0, IntPtr& bitmap) at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format) at TestFailExample.Function.FunctionHandler(String input, ILambdaContext context) in C:\work\graphics\TestFailExample\Function.cs:line 25 at lambda_method(Closure , Stream , Stream , LambdaContextInternal )

DllNotFoundException

DllNotFoundException

无法加载DLL'libdl':找不到指定的模块或其依赖项之一.\ n(HRESULT的异常:0x8007007E) 在Interop.Libdl.dlopen(字符串fileName,Int32标志) 在System.Drawing.SafeNativeMethods.Gdip.LoadNativeLibrary() 在System.Drawing.SafeNativeMethods.Gdip..cctor()

Unable to load DLL 'libdl': The specified module or one of its dependencies could not be found.\n (Exception from HRESULT: 0x8007007E) at Interop.Libdl.dlopen(String fileName, Int32 flag) at System.Drawing.SafeNativeMethods.Gdip.LoadNativeLibrary() at System.Drawing.SafeNativeMethods.Gdip..cctor()

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

I've seen this question, but there was no resolution.

重现此问题的最低代码是:

The minimum code to reproduce the issue is this:

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

只需创建一个.NET Core 2.0 Lambda函数项目,添加对System.Drawing.Common NuGet包的引用,然后将函数处理程序替换为上面的代码.在AWS上将其卡住并运行以获取错误.我注意到,在您尝试实际使用它之前,引用该程序包不会造成任何问题,但这可能取决于编译器的优化.

Simply create a .NET Core 2.0 Lambda function project, add a reference to the System.Drawing.Common NuGet package, and replace the function handler with the above code. Chuck it on AWS and run it to get the error. I've noted that referencing the package doesn't cause a problem until you try to actually use it, but this could be down to compiler optimizations.

我已经将MCVE打包到一个项目中,并将其上传到GitHub 此处为了简化人们重现此问题所必须执行的步骤.

I've packaged the MCVE into a project and uploaded it to GitHub here for the sake of simplifying the steps people have to go through to reproduce the issue.

我可以看到/lib64/libdl.so.2存在,但是/lib64/libdl.so不存在.由于似乎无法进行符号链接(只读文件系统),因此我不确定如何解决此问题.我已经尝试通过在/tmp中创建一个文件夹并将该文件符号链接为函数执行的第一件事来使用LD_LIBRARY_PATH环境变量.不幸的是,它似乎在这里查找所有库,因此该功能根本无法运行.我还尝试将LD_LIBRARY_PATH设置为/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/tmp,尽管我现在可以再次运行该功能,但这仍然无济于事,我只是遇到了相同的Gdip错误.

I can see that /lib64/libdl.so.2 exists, but /lib64/libdl.so does not. Since symlinking doesn't seem to be possible (read-only file system), I'm not sure how I can resolve this. I've tried using the LD_LIBRARY_PATH environment variable by creating a folder in /tmp and symlinking the file there as the first thing the function does. Unfortunately, it seems to look here for all libraries so the function doesn't run at all. I've also tried setting LD_LIBRARY_PATH to /var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/tmp and, although I could now run the function again, this still didn't help and I just get the same Gdip error.

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

I noted that /var/task/lib is already included in the LD_LIBRARY_PATH, so I tried packaging libdl.so and libgdiplus.so with my function, but this also failed, this time stating that entry point GdiplusStartup wasn't found in libdgiplus.so. These files weren't from an Amazon Linux instance, so I've now tried installing Mono and obtaining them from an Amazon Linux instance. This has not helped.

我已经尝试使用CoreCompat 绘图库,但这也报告了与,即使我尝试将其与功能捆绑在一起.

I've tried with the CoreCompat drawing library but this also reports problems pertaining to libgdiplus.so, even if I try and bundle that with the function.

此后,我在自己的Linux实例上进行了尝试,可以确认System.Drawing.Common是否有效.

I've tried since on my own Linux instance and can confirm that System.Drawing.Common works.

是否存在一些聪明的解决方案,可以让我在AWS Lambda上使用System.Drawing.Common?我可以通过另一种方法来伪装我的lambda函数以拥有libdl和工作吗?

Is there some clever solution that will allow me to use System.Drawing.Common on AWS Lambda? Is there another way I can fudge my lambda function to have libdl and work?

更新:

我们的最新尝试包括使用AWS Lambda层,并仔细提取apt在Docker Amazon Linux映像中安装的所有软件包,然后将其应用到它们自己的层中.尽管如此,我们最终还是归结为"libdl"问题,所以我们放弃了.

Our latest attempt involved using AWS Lambda Layers and carefully extracting all the packages installed by apt within the Docker Amazon Linux image, and then applying those to their own layer. Still we ultimately came down to the "libdl" issue, so we gave up.

人们建议图书馆遇到的许多问题是它们未正确显示日语文本,这对我们很重要.这似乎是一个问题,在AWS Lambda上并不会变得更好,这没有帮助,最终,在Go中重写我们的函数比继续使用C#更容易.

A lot of the issues with libraries people suggested are that they didn't render Japanese text correctly, which is important for us. This seems to be an issue which isn't going to get better on AWS Lambda it didn't help, and ultimately it was easier to rewrite our function in Go than continue using C# for this.

由于以下答案提到的库似乎适合一般用途-并且现在确实可能支持日语文本-我选择接受我确信可以在AWS Lambda上使用的答案.

Since the libraries mentioned by the answers below are seemingly suitable for general use - and may indeed support Japanese text now - I've chosen to accept the answer that I'm sure will work on AWS Lambda.

推荐答案

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

For image processing in .NET Core Lambda I use the SixLabors.ImageSharp

这是我在最近的AWS re:Invent演讲中使用的代码,该日志在进行图像处理时进行了记录:

Here is the code I used in my recent AWS re:Invent talk that did a log if image processing:

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;

这篇关于在AWS Lambda上使用System.Drawing.Common NuGet程序包时无法加载DLL'libdl'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆