ImageMagick のライブラリにある NewPixelRegionIterator 関数を C# コードから呼び出そうとしましたが、パラメータの受け渡しに問題が発生しました。
具体的には、NewPixelRegionIterator の定義は次のとおりです。
PixelIterator NewPixelRegionIterator(MagickWand *wand,const ssize_t x,
const ssize_t y,const size_t width,const size_t height)
この関数を C# コードにインポートするコードは次のとおりです。
[DllImport("libMagickWandDev.so")]
internal static extern PixelIterator NewPixelRegionIterator(IntPtr MagickWand,
IntPtr left, IntPtr top, UIntPtr width, UIntPtr height);
libMagickWand.soではなくlibMagickWandDev.soをインポートするという事実は、libMagickWandDev.so がデバッグ サポートを有効にしてコンパイルされているためです。そのため、gdb で mono を実行して、C 関数の呼び出しに問題があるかどうかを知ることができました (実際には、そうだった)。
gdb で見つかった問題は、次のように NewPixelRegionIterator を呼び出す場合です。
PixelIterator PixIt = PixelIteratorImports.NewPixelRegionIterator(MagickWandPtr,
new IntPtr(x), new IntPtr(y), new UIntPtr(1), new UIntPtr(1));
渡される実際のパラメーターは、gdb を介して次のとおりです。
Breakpoint 1, NewPixelRegionIterator (wand=0x7fffffffc7a8, x=10744336, y=5,
width=6, height=1) at wand/pixel-iterator.c:418
- 5 と 6 が適切ですが、これらは関数に渡される実際の数値です (ただし、xは 5 に等しく、yは 6 に等しくなければならず、幅と高さは両方とも 1 に等しくなります)。これは、パラメーターの順序が右にシフトされていることを意味し、0x7fffffffc7a8 はおそらく返される構造体の一部であるか、または他の何かです。
- それが役立つ場合、10744336はMagickWandPtr (Magick Wand のアドレス) の値です。これは、gdb でwandパラメーターをこれに設定し、 xを適切な値に設定すると、関数が正常に実行されるためです。
- PixelIterator は非常に慎重にマップされた構造体です (Marshal.SizeOf と実際の C コードの sizeof() による構造体のサイズが同じ 4192 バイトであることも確認しました)。
もう一度、よろしくお願いします。