Swig - 生成包装器以传递struct数组

时间:2014-06-27 14:42:17

标签: c# c swig

更新

我刚刚发现了%apply指令(例如see here)。不幸的是,我无法使用结构:

%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.

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

原帖

根据我的two previous帖子,我在C#中使用C库时仍然遇到问题。

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

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

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

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

  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;
  }

所以,在this comment之后,我修改了我的.i文件:

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

现在我可以建立我的&#34;假的&#34;使用new_image_t_arrayimage_t_array_setitem方法的数组,但是当我运行我的测试程序时,它会抛出System.AccessViolationException(它正在尝试&#34;读取或写入受保护的内存&# 34;)在pack方法调用(C#程序):

// 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 ++,指针和东西一无所知,所以它可能很明显......

谢谢!

1 个答案:

答案 0 :(得分:1)

我不知道它是否重要,无法测试,但您的.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);

包装器代码将调用包的C版本,为其提供数组,这是正常的,因为该函数采用指向image_t的指针,C知道如何使用数组作为指针。

更新:由于以上没有帮助,我看了arrays_csharp.i:它在所有基本类型上调用CSHARP_ARRAYSCSHARP_ARRAYS_FIXED宏,并且.i为尽管如此,SWIG中包含的数组示例仍会调用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"