Repository navigation
Closed
Description
DatabaseLoadOptions.DefaultStorageFactory に stream is FileStream の分岐があります。DatabaseLoadOptions.StorageFactory の既定値は DefaultStorageFactory なので、MemoryStream を渡す場合や StorageFactory に独自のものを渡す場合でも、この分岐はバイナリに含まれます。
FileStream の処理に必要なものが無い環境では、ファイルを使わない場合でも、この分岐のために DryDB を使えません。
起きていること
godot-dn2cpp(Godot の C# を C++ に変換して Web(wasm)に書き出すフォーク)4.7.2-dn2cpp.14.0 で、次のコードを書き出すと止まります(DryDB 1.1.0 に Header の Pack = 1(#44)だけを足した状態)。
var stream = new MemoryStream();
using (var builder = new DatabaseBuilder())
{
var table = builder.CreateTable("Item", KeyEncoding.Ascii);
table.Append("key", new byte[] { 42 });
await builder.BuildToStreamAsync(stream);
}
stream.Position = 0;
using var db = await ReadOnlyDatabase.OpenAsync(stream);
using var value = db.GetTable("Item").Get("key"u8);ERROR: Export .NET Project: 'DryDbWebRepro.so' imports symbols nothing in the exported page defines ... Unsatisfied:
SystemNative_PReadV
SystemNative_PWriteV
DefaultStorageFactory から FileStream の分岐を外すと、このエラーは出なくなり、ブラウザでも動きました。
手元で回避に使った変更(参考)
FileStream の分岐を、OpenFileAsync だけが通る経路に移しました。
public static readonly StorageFactory DefaultStorageFactory = (stream, pageSize) =>
{
- if (stream is FileStream fs)
- {
- return new PreadPageLoader(fs.SafeFileHandle);
- }
-
if (stream is MemoryStream ms)
{
return new InMemoryPageLoader(ms.ToArray());
+static class FileStorage
+{
+ public static readonly StorageFactory Factory = (stream, pageSize) => stream is FileStream fs
+ ? new PreadPageLoader(fs.SafeFileHandle)
+ : DatabaseLoadOptions.DefaultStorageFactory(stream, pageSize);
+}
public static async ValueTask<ReadOnlyDatabase> OpenFileAsync(string path, DatabaseLoadOptions? options = null, CancellationToken cancellationToken = default)
{
options ??= DatabaseLoadOptions.Default;
+ if (options.StorageFactory == DatabaseLoadOptions.DefaultStorageFactory)
+ {
+ options = options with { StorageFactory = FileStorage.Factory };
+ }この変更では、OpenAsync(fileStream) で FileStream を直接渡したときの挙動が変わります(PreadPageLoader ではなく NotSupportedException になる)。
dn2cpp はかなり特殊な環境なので、サポートの対象になるかは分かりません。もし差し支えなければ、ファイルを使わないときに FileStream の分岐がバイナリに含まれない形にしていただけると、とても助かります。形はもちろんお任せします。
環境
- godot-dn2cpp 4.7.2-dn2cpp.14.0(Web、スレッドなし)
- DryDB 1.1.0。main(6b17592)の
DefaultStorageFactoryも同じ形です - .NET SDK 10.0.403、Windows 11 x64
Metadata
Metadata
Assignees
Labels
No labels
Activity
hadashiA commentedon Nov 8, 2026
ご報告ありがとうございます。迷いましたが、ご提案の形の対応を #47 で入れました。
備考:
FileStreamは BCL 標準の型なので、C#ライブラリ側としては「標準の型の実装がターゲットに無い」ことを通常は想定していないと思います。PlatformNotSupportedExceptionを投げるのが .NET の標準的な流儀だと思うので、本来はランタイム/変換器側で吸収してほしい類の問題だと思いました。PreadPageLoaderがビルドに含まれていることは、 dn2cpp に限らず、NativeAOTやUnity IL2CPP環境等でもトリミングの無駄が生じると思われるので、避ける価値があると判断しました。