代码之家  ›  专栏  ›  技术社区  ›  ProgrammingLlama Raveena Sarda

在aws lambda上使用system.drawing.common nuget包时无法加载dll“libdl”

  •  11
  • ProgrammingLlama Raveena Sarda  · 技术社区  · 7 年前

    我们有一个缩略图生成器lambda函数,我正试图将其更新为.NET Core 2.0,但在使用Microsoft的 System.Drawing.Common Nuget包:

    类型初始化异常

    “gdip”的类型初始值设定项引发异常。 位于system.drawing.safenativemethods.gdip.gdipcreateBitMapFromScan0(Int32宽度,Int32高度,Int32跨距,Int32格式,handleRef扫描0,IntPtr&位图) at system.drawing.bitmap..ctor(int32宽度,int32高度,像素格式) 在c:\ work\graphics\testfailexample\function.cs中的testfailexample.function.functionhandler(字符串输入,ilambdacontext上下文)中:第25行 在lambda_方法(闭包、流、流、lambdacontexternal)

    引起

    无法加载dll“libdl”:找不到指定的模块或其依赖项之一。\n(hresult的异常:0x8007007e) 在interop.libdl.dlopen(字符串文件名,int32标志) 在system.drawing.safenativemethods.gdip.loadNativeLibrary() 在system.drawing.safenativemethods.gdip..cctor()

    我见过 this 问题,但没有解决办法。

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

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

    只需创建一个.net core 2.0lambda函数项目,添加对 系统.绘图.通用 nuget包,并用上面的代码替换函数处理程序。把它扔到aws上运行它来得到错误。我已经注意到,在尝试实际使用包之前,引用包不会造成问题,但这可能取决于编译器优化。

    我已经将mcve打包成一个项目并上传到github here 为了简化人们为了重现这个问题必须经历的步骤。

    我看得出来 /lib64/libdl.so.2 存在,但是 /lib64/libdl.so 没有。由于符号链接似乎不可能(只读文件系统),我不确定如何解决这个问题。我试过用 LD_LIBRARY_PATH 通过在中创建文件夹来创建环境变量 /tmp 把文件符号化,这是函数的第一步。不幸的是,它似乎在这里寻找所有的库,所以函数根本不运行。我也试过设置 图书馆路径 /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,但这也失败了,这次声明了入口点 GdiplusStartup 在中找不到 libdgiplus.so . 这些文件不是来自amazon linux实例,所以我现在尝试安装mono并从amazonlinux实例获取它们。这没有帮助。

    我试过和CoreCompat在一起 drawing library 但这也报告了与 libgdiplus.so ,即使我尝试将其与函数捆绑在一起。

    从那以后,我就在自己的Linux实例上尝试过,并且可以确认 系统.绘图.通用 作品。

    有什么聪明的办法可以让我用 系统.绘图.通用 关于aws lambda?有没有其他方法可以让我的lambda函数有libdl和工作?

    更新:

    我们最新的尝试包括使用aws lambda层,仔细提取apt在docker amazon linux映像中安装的所有包,然后将它们应用到自己的层。不过,我们最终还是谈到了“libdl”问题,所以我们放弃了。

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

    由于下面的答案中提到的库似乎适合一般使用,而且现在可能确实支持日语文本,所以我选择接受这个答案,我相信它将在aws lambda上工作。

    3 回复  |  直到 6 年前
        1
  •  0
  •   Norm Johanson    6 年前

    对于.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;
    
        2
  •  3
  •   Dijkgraaf José Ignacio Gutiérrez Guzmán    6 年前

    在运行dotnet core 2.1.500版本的ubuntu 18服务器上上传应用程序后,我也遇到了同样的问题。我用这个解决方案解决了这个问题 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/*
    

    这解决了问题。

        3
  •  1
  •   Alex HG    6 年前

    我找到了解决这个问题的方法,对我很有帮助:

    起初,我从项目中删除了system.drawing.common库,然后安装了可以找到的库 here 。它使用相同的类。

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

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