更新
我刚刚发现了 %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);
现在我可以使用 new_image_t_array
和 image_t_array_setitem
方法构建我的“假”数组,但是当我运行我的测试程序时,它抛出一个 System.AccessViolationException
(它试图在 pack
方法调用(C# 程序)中“读取或写入 protected 内存”):
// 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++、指针和其他东西一无所知,所以这可能是显而易见的......
谢谢!
最佳答案
我不知道这是否重要,无法测试,但您的 .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 版本的 pack,为其提供数组,这没问题,因为该函数采用指向 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"
关于c# - Swig - 生成包装器以传递结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24454601/