2

我一直在尝试从 C# 代码调用 ImageMagick 库中的 NewPixelRegionIterator 函数,并且遇到了参数传递问题。
更具体地说,这里是 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);

我导入libMagickWandDev.so而不是libMagickWand.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参数设置为 this 并将x设置为合理的值会使函数运行得很好。
  • PixelIterator 是一个非常仔细映射的结构(我还通过 Marshal.SizeOf 验证了结构的大小和实际 C 代码的 sizeof() 是相同的 4192 字节)

再次,提前感谢。

4

1 回答 1

2

你确定你可以从 PInvoke 函数返回一个结构吗?您不需要使用输出参数/指针返回它吗?

因为参数被移动了,所以我希望 PixelIterator* 类型的隐藏参数作为第一个或最后一个参数。并且返回类型为 void。这就是 C 编译器在底层实现结构返回函数的方式。

在评论中,您解释说返回 PixelIterator* 可以解决问题。其原因可能是 C 函数正在分配一个对象并返回其指针。但是,该定义没有给出任何线索……无论如何,当您完成返回的对象时,您可能需要释放该内存。

于 2012-04-06T21:23:36.527 回答