none
Gdiplus.dllの仕様に関するドキュメントはありませんか? RRS feed

  • Question

  • .NET Frameworkの内部実装を読んで勉強をしています。

    現在System.Drawing.Bitmapクラスを読んでおり、内部でGdiPlus.dllの関数を呼び出していることがわかりました。

    このGdiPlus.dllの仕様について、何かしらのドキュメントとしてまとまっているものはありませんか?

    ドキュメント以外でも、どうにかしてGdiPlus.dll内の各関数の挙動を知る方法はありませんか?

    内部実装を読めばBitmapクラスの仕組みがわかると思ったのですが、結局メイン部分がdllに委譲されているので

    よくわからずに困っています。

    Tuesday, October 8, 2019 2:59 PM

All replies

  • GDI+ は SDK としてもクラスとしてで見せているものですので、.NET Framework のクラスとほぼ同じ見せ方になっています。
    https://docs.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-bitmap-flat

    ドキュメントといえば、上記のものはあります。
    多少、.NET Framework 側のドキュメントより細かく書いてはありますが、内部挙動がわかるレベルではない認識です。

    ところで、「内部実装を読むことで勉強する」とありますが、どういったことを目指しているのでしょうか?
    たとえば、Windows Forms も根底では Win32API を呼び出しているので、最終的な内部実装を知ることはできません。
    このため、内部実装を読むことは本来、プログラミングに必須とは言えませんので、なぜ「内部実装を読んで勉強している」のかが気にかかりました。

    Tuesday, October 8, 2019 9:12 PM
    Moderator
  • ご回答頂きありがとうございます。

    内部実装を読んでいる理由ですが、MSDNに書かれている情報を読んだだけでは

    メソッドの挙動がよくわからない場合があると思ったためです。

    たとえば、BitmapクラスのStringを引数に取るコンストラクタには

    「Bitmapが破棄されるまで、ファイルはロックされたままになります」という記述があり、

    Bitmap bitmap1 = new Bitmap("image.bmp");

    とした場合に、bitmap1がファイルをロックすることはわかりますが、

    Bitmap bitmap2 = new Bitmap(bitmap1);

    とした場合、bitmap2もファイルをロックするのか?といった疑問は、MSDNの記述だけでは

    必ずしも明らかにならないと思います。

    このような場合、メソッドの詳細な挙動を知るためには内部実装を読むしかないと考えているのですが、

    この勉強方法は間違っているのでしょうか? ご教示いただければ幸いです。




    • Edited by XX0052 Wednesday, October 9, 2019 4:01 PM
    Wednesday, October 9, 2019 3:59 PM
  • 疑問点は「なるほど」と思いました。が、他のキーワードから、理屈としては、bitmap2はファイルをロックしないはず、ということが言えます。

    Bitmap bitmap2 = new Bitmap(bitmap1);

    の書き方の場合、bitmap1を元にして「新しいインスタンス」を作る旨がMSDNに記述されています。この「新しいインスタンス」がミソでして、bitmap1が参照しているインスタンス(これはファイルimage.bmpと結びついている)と、bitmap2が参照しているインスタンスは別ものであることを意味しています。

    試しに、この後に、bitmap1をdisposeしてみてください。そうすると、ファイルimage.bmpのロックは解けます。一方で、bitmap2が参照するインスタンスは存続していて、例えば表示させることが可能です。

    • Edited by 外池 Wednesday, October 9, 2019 7:54 PM
    Wednesday, October 9, 2019 7:53 PM
  • 疑問は理解できますが、「実装を調べることや振る舞いを観察することで解決する」は危ないですね。
    ドキュメントに書かれていない内部実装・振る舞いについては変更されることがあるからです。
    GDI+ の内部実装は Windows のバージョンによって異なりますので、なお注意です。

    今回の「ファイルがロックされたままになるかわからない」ことについて対策するなら、「new Bitmap(bitmap1.Width, bitmap1.Height) で作っておいて Graphics.DrawImage や LockBits を使ってコピーを作る」、「ファイル名や FileStream を渡すのではなく、MemoryStream を渡す」など、ロックされることを回避する実装が考えられます。
    そういう風に「ドキュメントに書かれていない不確かなこと(リスク)を回避する」が多いです。

    Wednesday, October 9, 2019 9:18 PM
    Moderator
  • XX0052さん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    質問に対しては、Microsoft ドキュメントで「ビットマップが破棄されるまでファイルはロックされたまま」という文の正確な意味を知りたいと考えています。こちらもやってみました。

    コード:
    Bitmap tmpBmp = new Bitmap(path);
                FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                StreamWriter sw = new StreamWriter(fs);
                sw.WriteLine("123");
                sw.Flush();
                sw.Close();
                fs.Close();
    

    やってみて、次のことが出てきました:

    ビットマップのコピーを作成し、元のものを解放することによって問題を解決しました。
    コード:

    string path = @"D:\Images\test.jpg";
                Bitmap tmpBmp = new Bitmap(path);
                Bitmap image = new Bitmap(tmpBmp);
                tmpBmp.Dispose();
                FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                StreamWriter sw = new StreamWriter(fs);
                sw.WriteLine("123");
                sw.Flush();
                sw.Close();
                fs.Close();
                MessageBox.Show("Success");
    
    結果:

    また、この問題に関するより多くの解決策については、次のリファレンスを参照してください。

    C# Free Image file from use

    どうぞよろしくお願いします。



    MSDN/ TechNet Community Support Haruka
    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    Friday, October 11, 2019 10:14 AM
    Moderator