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

更新

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

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

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

原帖

在我之前的 两篇post之后,我仍然在使用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; } 

所以,在这条评论之后 ,我修改了我的.i文件:

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

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

 // the "images" variable is a List 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); 

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

知道为什么会这样吗? 正如我在其他post中所说,我对C / C ++,指针和内容一无所知,所以它可能很明显……

谢谢 !

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

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

此外,没有什么能迫使您声明完全相同的签名。 你可能有这样的事情:

 %module packer_cs %include  %{ #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宏,并且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"