我有一个缩略图生成器lambda函数,我正在尝试更新到.NET Core 2.0,但是在使用Microsoft的System.Drawing.Common
NuGet包时遇到以下错误:
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()
我见过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上并运行它以获取错误。我已经注意到,在尝试实际使用它之前引用该包不会导致问题,但这可能归结为编译器优化。
我已将MCVE打包成一个项目并将其上传到GitHub here,以简化人们为重现问题而必须完成的步骤。
我可以看到/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 drawing library,但这也报告了与libgdiplus.so
有关的问题,即使我尝试将其与该函数捆绑在一起。
我已经在我自己的Linux实例上尝试过并且可以确认System.Drawing.Common
有效。
是否有一些聪明的解决方案可以让我在AWS Lambda上使用System.Drawing.Common
?还有另一种方法可以捏造我的lambda函数来拥有libdl并工作吗?
更新:
我们最近的尝试涉及使用AWS Lambda Layers并仔细提取Docker Amazon Linux映像中apt安装的所有软件包,然后将这些软件包应用到他们自己的层。我们最终归结为“libdl”问题,所以我们放弃了。
图书馆人员提出的许多问题是他们没有正确地呈现日文文本,这对我们很重要。这似乎是一个在AWS Lambda上没有变得更好的问题它没有帮助,最终在Go中重写我们的函数比继续使用C#更容易。
由于以下答案提到的图书馆似乎非常适合一般用途 - 现在可能确实支持日文文本 - 我选择接受我肯定会在AWS Lambda上工作的答案。
对于.NET Core Lambda中的图像处理,我使用SixLabors.ImageSharp
以下是我在最近的AWS re:Invent talk中使用的代码,如果图像处理,它会执行日志:
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;
在运行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/*
这解决了问题。