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_array
和image_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_ARRAYS
和CSHARP_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"