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

标签 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);

现在我可以使用 new_image_t_arrayimage_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_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"

关于c# - Swig - 生成包装器以传递结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24454601/

相关文章:

c# - 操作未在分配的超时 00 :01:00 内完成

c - 类似位运算符之间的区别

java - 将java函数注册为C函数中的回调

c# - 使用反射是一种设计味道吗?

c# - Linq 左外连接计数

c - 循环展开,性能实验室

c - POSIX 名称信号量在进程退出后不释放

python - SWIG 输入类型(C++ 到 Python)

python - 添加到 C 代码的函数和无法识别的 swig 接口(interface); "no attribute ' set_latency'”

c# - 如何正确使用 Azure.AI.OpenAI.OpenAIClient.GetChatCompletionsStreamingAsync 方法