Невозможно загрузить DLL 'libdl' при использовании пакета System.Drawing.Common NuGet на AWS Lambda - PullRequest
0 голосов
/ 31 мая 2018

У нас есть лямбда-функция генератора миниатюр, которую я пытаюсь обновить до .NET Core 2.0, но я столкнулся со следующей ошибкой при использовании пакета Microsoft System.Drawing.Common NuGet:

TypeInitializationException

Инициализатор типа для Gdip выдал исключение.в System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0 (ширина Int32, высота Int32, шаг Int32, формат Int32, сканирование HandleRef0, IntPtr & bitmap) в System.Drawing.Bitmap..ctor (ширина Int32, высота Int32, формат PixelFormat) в TestFailExample.Function.FunctionHandler (String input, контекст ILambdaContext) в C: \ work \ graphics \ TestFailExample \ Function.cs: строка 25 в lambda_method (закрытие, поток, поток, LambdaContextInternal)

, вызванная

DllNotFoundException

Невозможно загрузить DLL 'libdl': указанный модуль или одна из его зависимостей не найдены. \ N (Исключение из HRESULT: 0x8007007E) в Interop.Libdl.dlopen (String fileName, флаг 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, добавьте ссылку на пакет NuGet System.Drawing.Common и замените обработчик функции приведенным выше кодом.Подбрось его на 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?Есть ли другой способ, которым я могу использовать свою лямбда-функцию для работы libdl?

Обновление:

Наша последняя попытка включала использование AWS Lambda Layers и тщательное извлечение всех пакетов.устанавливается apt в образе Docker Amazon Linux, а затем применяется к их собственному слою.Тем не менее, мы в конечном итоге перешли к проблеме «libdl», поэтому мы отказались.

Многие проблемы с библиотеками, которые люди предложили, заключаются в том, что они неправильно отображают японский текст, что важно для нас.Похоже, что это проблема, которая не улучшится на AWS Lambda, это не помогло, и в конечном итоге было проще переписать нашу функцию в Go, чем продолжать использовать C # для этого.

Поскольку библиотеки, упомянутые в ответах ниже, кажутся подходящими для общего использования - и могут действительно поддерживать японский текст сейчас - я решил принять ответ, который, я уверен, будет работать на AWS Lambda.

Ответы [ 3 ]

0 голосов
/ 26 марта 2019

Я нашел решение этой проблемы, которое сработало для меня:

Сначала я удалил библиотеку System.Drawing.Common из проекта, затем я установил библиотеку, которую вы можете найти здесь .Он использует те же классы.

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

Наконец я установил эту другую библиотеку, которая содержит все необходимые библиотеки dll для использования библиотек чертежей в Linux и Lambda.Выполнив эти действия, вы сможете без проблем загрузить код в AWS.

0 голосов
/ 09 апреля 2019

У меня возникла та же проблема после загрузки приложения на сервер Ubuntu 18 с версией dotnet core 2.1.500.Я решил эту проблему с помощью этого решения https://github.com/dotnet/dotnet-docker/issues/618, используя предложения MichaelSimons.

Я запустил

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

Это решило проблемы.

0 голосов
/ 05 декабря 2018

Для обработки изображений в .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;
...