使用SWIG将错误的值作为参数传递给C库

本文关键字:参数传递 SWIG 错误 使用 | 更新日期: 2023-09-27 18:10:51

在我之前的三篇文章之后,我现在可以将一个托管数组的结构传递给我的包装方法。以下是这些文件的摘录:

// packer.i
typedef struct {
  int width; // input
  int height; // input
  frame_t view; // output
  frame_t dest; // output
} image_t;
CSHARP_ARRAYS(image_t, image_t)
%apply image_t INOUT[] { image_t *images }
int pack(image_t *images, int nb_images, parameters_t params);

生成一个签名如下的函数:

// packer_cs.cs
public static int pack(image_t[] images, int nb_images, parameters_t arg2)
我这样称呼

// Program.cs
var files = Directory.GetFiles("./images");
var images = new image_t[files.Length];
for (var f = 0; f < files.Length; f++)
{
    using (var imgInfo = Image.FromFile(files[f]))
    {
        var imgStruct = new image_t()
                        {
                            width = imgInfo.Width,
                            height = imgInfo.Height,
                            dest = new frame_t(),
                            view = new frame_t()
                        };
        images[f] = imgStruct;
    }
}
var result = packer_cs.pack(images, images.Length, new parameters_t());

一切都很好,但是当我运行pack()方法时,我有一个受保护的内存访问问题(System.AccessViolationException)。谢天谢地,我可以访问C库的源代码,只要我启用非托管代码调试,Visual Studio就会自动打开它进行调试和逐步执行。

因此,如果我在pack()函数的开始添加一个断点,并且我使用手表检查images[x],我可以看到宽度和高度值与提供的内容无关(有时它甚至是0或负)。这是怎么呢如果我在c#端检查我的托管数组,值被正确地存储和检索。为什么C不能得到正确的值?其他参数(nb_images和params)没有任何问题。

使用SWIG将错误的值作为参数传递给C库

执行以下操作:

  1. 检查images[f].width和height是否有您期望的值
  2. 如果是,则检查swig生成的代码,以验证这些字段是否被正确复制。
  3. 如果你不能通过查看代码发现任何问题,你应该在packer_cs.pack上中断,并使用调试器查看将c#数组复制到c++数组的包装器代码,看看哪里出了问题。

可能是typemaps中的某些内容不正确。一旦你知道那是什么,你可以复制typemaps代码从源(csharp_array痛饮。