サムネイル ジェネレーターの Lambda 関数を .NET Core 2.0 に更新しようとしていますが、Microsoft のSystem.Drawing.Common
NuGet パッケージを使用すると次のエラーが発生しました。
タイプ初期化例外
'Gdip' の型初期化子が例外をスローしました。System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32 width, Int32 height, Int32 stride, Int32 format, HandleRef scan0, IntPtr& bitmap)、System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)、TestFailExample.Function.FunctionHandler(String input, ILambdaContext context)、C:\work\graphics\TestFailExample\Function.cs:line 25、lambda_method(Closure、Stream、Stream、LambdaContextInternal)
のせいで
DllNotFoundException
DLL 'libdl' をロードできません: 指定されたモジュールまたはその依存関係の 1 つが見つかりませんでした。\n (HRESULT からの例外: 0x8007007E) at Interop.Libdl.dlopen(String fileName, Int32 flag) at System.Drawing.SafeNativeMethods.Gdip.LoadNativeLibrary() at 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 関数プロジェクトを作成し、NuGet パッケージへの参照を追加してSystem.Drawing.Common
、関数ハンドラーを上記のコードに置き換えるだけです。これを AWS に投入して実行すると、エラーが発生します。パッケージを参照しても、実際に使用してみるまでは問題は発生しないことに気付きましたが、これはコンパイラの最適化によるものである可能性があります。
MCVEをプロジェクトにパッケージ化し、GitHubにアップロードしました。ここ問題を再現するためにユーザーが実行する必要がある手順を簡素化するためです。
が存在することはわかります/lib64/libdl.so.2
が、/lib64/libdl.so
存在しません。シンボリックリンクは不可能なようです (読み取り専用ファイル システム) ので、これを解決する方法がわかりません。関数が最初に行うこととしてLD_LIBRARY_PATH
、 にフォルダーを作成し、そこにファイルのシンボリックリンクを作成することで、環境変数を使用しようとしました。残念ながら、すべてのライブラリをここで検索しているようで、関数はまったく実行されません。に/tmp
設定することも試しましたが、関数を再度実行できるようになりましたが、それでも役に立たず、同じ Gdip エラーが発生します。LD_LIBRARY_PATH
/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/tmp
/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
動作することが確認できました。
AWS Lambda で使用できるような巧妙な解決策はありますかSystem.Drawing.Common
? Lambda 関数を改造して libdl を動作させる別の方法はありますか?
アップデート:
私たちの最新の試みは、AWS Lambda レイヤーを使用し、Docker Amazon Linux イメージ内で apt によってインストールされたすべてのパッケージを慎重に抽出し、それらを独自のレイヤーに適用することでした。それでも最終的には「libdl」の問題に行き着いたため、断念しました。
皆さんが指摘したライブラリの問題の多くは、日本語のテキストが正しくレンダリングされないというものでした。これは私たちにとって重要な問題です。これは AWS Lambda では改善されない問題のようで、役に立ちませんでした。結局、C# を使い続けるよりも、関数を Go で書き直す方が簡単でした。
以下の回答で言及されているライブラリは一般的な使用に適しているようで、実際に日本語のテキストをサポートしている可能性があるため、AWS Lambda で確実に機能する回答を受け入れることにしました。
ベストアンサー1
dotnet core 2.1.500バージョンを実行しているUbuntu 18サーバーにアプリケーションをアップロードした後、同じ問題が発生しました。この解決策でこの問題を解決しました。https://github.com/dotnet/dotnet-docker/issues/618MichaelSimons の提案を使用します。
私は走った
#sudo apt-get update
#sudo apt-get install -y --allow-unauthenticated \
libc6-dev \
libgdiplus \
libx11-dev \
#sudo rm -rf /var/lib/apt/lists/*
これにより問題は解決しました。