C# 无法加载DLL';libdl';在AWS Lambda上使用System.Drawing.Common NuGet包时

C# 无法加载DLL';libdl';在AWS Lambda上使用System.Drawing.Common NuGet包时,c#,aws-lambda,.net-core-2.0,C#,Aws Lambda,.net Core 2.0,我们有一个缩略图生成器lambda函数,我正在尝试将其更新为.NET Core 2.0,但在使用Microsoft的System.Drawing.CommonNuGet软件包时遇到以下错误: 类型初始化异常 “Gdip”的类型初始值设定项引发异常。 位于System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32宽度、Int32高度、Int32步幅、Int32格式、HandleRef scan0、IntPtr和位图)

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

类型初始化异常

“Gdip”的类型初始值设定项引发异常。 位于System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32宽度、Int32高度、Int32步幅、Int32格式、HandleRef scan0、IntPtr和位图) at System.Drawing.Bitmap..ctor(Int32宽度、Int32高度、像素格式) 在C:\work\graphics\TestFailExample\Function.cs中的TestFailExample.Function.FunctionHandler(字符串输入,ILambdaContext上下文)处:第25行 在lambda_方法下(闭包、流、流、LambdaContenternal)

引起

DllNotFoundException

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

我看到了这个问题,但并没有解决

再现问题的最低代码如下:

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,以简化人们复制问题所需的步骤

我可以看到
/lib64/libdl.so.2
存在,但
/lib64/libdl.so
不存在。由于符号链接似乎不可能(只读文件系统),我不确定如何解决这个问题。我尝试使用
LD\u LIBRARY\u 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_路径中,所以我尝试用我的函数打包libdl.so和libgdiplus.so,但这也失败了,这次声明在
libdgiplus.so
中找不到入口点
GdiplusStartup
。这些文件不是来自AmazonLinux实例,所以我现在尝试安装Mono并从AmazonLinux实例获取它们。这没有帮助

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

从那以后,我在自己的Linux实例上进行了尝试,可以确认
System.Drawing.Common
可以正常工作

是否有一些聪明的解决方案允许我在AWS Lambda上使用
System.Drawing.Common
?有没有其他方法可以使lambda函数具有libdl并工作

更新:

我们的最新尝试涉及使用AWS Lambda层,并仔细提取Docker Amazon Linux映像中apt安装的所有包,然后将这些包应用到它们自己的层。但我们最终还是谈到了“libdl”问题,所以我们放弃了

图书馆的许多人提出的问题是,他们没有正确地呈现日语文本,这对我们很重要。这似乎是一个在AWS Lambda上不会变得更好的问题,它没有帮助,最终在Go中重写我们的函数要比继续使用C#更容易


由于以下答案中提到的库似乎适合于一般用途,而且现在可能确实支持日文文本,因此我选择接受这个答案,我确信这个答案将适用于AWS Lambda。

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

下面是我在最近的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;

我为这个问题找到了一个对我有效的解决方案:

首先,我从项目中删除了System.Drawing.Common库,然后安装了您可以找到的库。它使用相同的类

using System.Drawing
...
var bmp = new Bitmap(100,100);

最后,我安装了另一个库,其中包含在Linux和Lambda上使用绘图库所需的所有dll。通过执行这些步骤,代码可以毫无问题地上传到AWS。

在运行dotnet core 2.1.500版本的Ubuntu 18服务器上上传应用程序后,我也遇到了同样的问题。我用MichaelSimons的建议解决了这个问题

我跑

#sudo apt-get update
#sudo apt-get install -y --allow-unauthenticated \
        libc6-dev \
        libgdiplus \
        libx11-dev \ 
#sudo rm -rf /var/lib/apt/lists/*

这解决了问题。

如果使用centOS,则下面的命令会有所帮助

  • sudo yum安装libgdiplus

这似乎是因为
libdl。所以O.s上缺少了
。请检查:@Gusman我从我的问题中链接的问题中收集了很多信息,但我似乎找不到一种方法来成功地解决这个问题以使我的函数工作。@John你找到方法了吗?我有同样的问题使用PdfSharp/MigraDoc也有同样的问题。使用ClosedXML+1解决同样的问题真的很糟糕,因为它可能会解决其他人的问题,但不幸的是,我尝试它时,它对日语文本不起作用。如果你不能解决他们的问题,你不能告诉他们完全尝试不同的范例。他问如何让System.Drawing.Common在AWS Lambda上工作-你甚至没有尝试回答这个问题。而