2012-04-06 95 views
2

我一直在尝试从C#代码调用ImageMagick库中的NewPixelRegionIterator函数,并且已经运行到参数传递问题。
更具体地说,这里是NewPixelRegionIterator的定义:P /调用传递给C库函数的错误参数

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可能是要返回的结构的一部分或其他东西。
  • 如果有帮助,是MagickWandPtr(该Magick魔杖的地址)的值,因为设置参数,这和X到一个理智的价值,而在gdb使得功能运行正好。
  • PixelIterator是非常小心地映射(我也已经验证了该结构的通过Marshal.SizeOf)的大小和实际的C代码的的sizeof(是相同的4192个字节)

再次一个结构,由于提前。

+0

检查C api使用的调用对话。你最可能的选择是Cdecl或stdcall。 DllImportAttribute的默认值是WinApi,它将默认在除Win CE以外的任何其他位置进行调用。 – user957902 2012-04-06 21:17:48

+0

您确定只能从PInvoke函数返回结构吗?你不需要使用参数/指针返回它吗? – usr 2012-04-06 21:19:32

+0

我猜想问题的一部分是'size_t'的宽度...它可能是32位,但是你传递的是IntPtr,它将在64位系统上为64位。 (另外,你为什么使用一些参数的UIntPtr和其他的IntPtr?)但是想想看,值被推到了右边,所以也许你正在用64位指针调用一个32位函数?尝试在32位进程中运行整个事情。 – phoog 2012-04-06 21:19:39

回答

2

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

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

在您解释说返回一个PixelIterator *解决了这个问题。原因可能是C函数正在分配一个对象并返回它的指针。虽然这个定义没有给出线索,但是......无论如何,当你完成返回的对象时,你可能需要释放内存。

+0

我不知道C编译器在这方面的行为。我已经改变了我的导入代码,以包含一个“out IntPtr ReturnValue”作为第一个参数,并且是无效返回类型,但参数仍然传递不正确。你知道一个来源,进一步详细解释如何做到这一点? – 2012-04-06 21:33:22

+0

你有没有尝试添加这个参数作为最后一个参数?也尝试在列表的开始和结尾添加1-2个填充参数。 – usr 2012-04-06 21:35:05

+0

继续关于实际返回指针的C函数的想法,我想也许我只需要给我的导入方法一个IntPtr返回类型,而不包括任何其他参数。看起来你是对的!将指针指向的值转换为结构后,我成功地访问了它的成员。如果你只能编辑你的答案,我会给你正确的答案。 – 2012-04-06 21:38:09

相关问题