У нас есть лямбда-функция генератора эскизов, которую я пытаюсь обновить до .NET Core 2.0, но я столкнулся со следующей ошибкой при использовании пакета Microsoft System.Drawing.Common
NuGet:
TypeInitializationException
Инициализатор типа для Gdip выдал исключение. в System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0 (ширина Int32, высота Int32, шаг Int32, формат Int32, HandleRef scan0, IntPtr & bitmap) в System.Drawing.Bitmap..ctor (ширина Int32, высота Int32, формат PixelFormat) в TestailExEx.Function.FunctionHandler (ввод строки, контекст 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
окружения 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, чем продолжать использовать С# для этого.
Поскольку библиотеки, упомянутые в ответах ниже, кажутся подходящими для общего использования - и могут действительно поддерживать текст на японском языке - я решил принять ответ, который, я уверен, будет работать на AWS Lambda.