Swig-生成包装器以传递结构的数组

本文关键字:结构 数组 包装 Swig- | 更新日期: 2023-09-27 18:10:28

更新

我刚刚了解了%apply指令(例如,请参阅此处(。不幸的是,我无法使用structs:

%module packer_cs
%include "carrays.i"
%{
    #include "packer.h" 
%}
%include "typemaps.i"
%include "arrays_csharp.i"
%apply image_t INPUT[] { image_t *images }
%include "packer.h"

这导致:

swig -csharp -outdir bin'csharp packer'packer.i
Warning 453: Can't apply (image_t INPUT[]). No typemaps are defined.

我找不到任何有关此警告的文档。看起来我必须定义一个自定义的类型映射,但我不知道从哪里开始。我越来越厌倦了文档的缺乏,也非常渴望有一天能成功地编写我的包装:(

原始帖子

继我之前的两篇文章之后,我在C#中使用C库仍然存在问题。

概括一下:我有一个C库,我正在尝试使用Swig编写一个C#包装器。

在.h文件中,方法声明为:

int pack(image_t *images, int nb_images, parameters_t params);

实际上,*images总是被传递一个数组。如果我只是在C#文件中生成这样的swig文件,那么函数需要一个实例:

  public static int pack(image_t images, int nb_images, parameters_t arg2) {
    int ret = packer_csPINVOKE.pack(image_t.getCPtr(images), nb_images, parameters_t.getCPtr(arg2));
    if (packer_csPINVOKE.SWIGPendingException.Pending) throw packer_csPINVOKE.SWIGPendingException.Retrieve();
    return ret;
  }

所以,在这个评论之后,我修改了我的.I文件,这样:

%module packer_cs
%include <carrays.i>
%{
    #include "packer.h" 
%}
%include "packer.h"
%array_functions(image_t, image_t_array);

现在我可以使用new_image_t_arrayimage_t_array_setitem方法构建我的"伪"数组,但当我运行测试程序时,它会在pack方法调用(C#程序(上抛出一个System.AccessViolationException(它试图"读取或写入受保护的内存"(:

// the "images" variable is a List<image_t>
var images_array = packer_cs.new_image_t_array(images.Count);
for (var i = 0; i < images.Count; i++)
{
    packer_cs.image_t_array_setitem(images_array, i, images[i]);
}
// this throws the exception
var result = packer_cs.pack(images_array, images.Count, param);

实际上,异常是在Swig生成的C#文件中的int ret = packer_csPINVOKE.pack(image_t.getCPtr(images), nb_images, parameters_t.getCPtr(arg2));行抛出的。

你知道为什么会发生这种事吗?正如我在其他帖子中所说,我对C/C++、指针之类的东西一无所知,所以这可能是显而易见的。。。

谢谢!

Swig-生成包装器以传递结构的数组

我不知道这是否重要,不能测试,但你的.I可能必须在array_functions之后导出pack函数:

%module packer_cs
%include <carrays.i>
%{
    #include "packer.h" 
%}
%array_functions(image_t, image_t_array);
%include "packer.h"

此外,没有任何东西强迫您声明完全相同的签名。你可能有这样的东西:

%module packer_cs
%include <carrays.i>
%{
    #include "packer.h" 
%}
// export image_t and parameters_t, then: 
int pack(image_t images[], int nb_images, parameters_t params);

包装器代码将调用pack的C版本,并为其提供数组,这是可以的,因为函数使用指向image_t的指针,而C知道如何将数组作为指针。

更新:由于以上内容没有帮助,我查看了arrays_csharp.i:它在所有基本类型上调用CSHARP_ARRAYSCSHARP_ARRAYS_FIXED宏,而SWIG中包含的数组示例的.I仍然调用apply,因此%apply可能不会自动执行此操作。事实上,这两个宏看起来是类型映射,所以我认为值得一试:

%module packer_cs
%include "carrays.i"
%{
    #include "packer.h" 
%}
%include "typemaps.i"
%include "arrays_csharp.i"
CSHARP_ARRAYS(image_t, image_t)
CSHARP_ARRAYS_FIXED(image_t, image_t)
%apply image_t INPUT[] { image_t *images }
%include "packer.h"