如何要求 SWIG 以不同方式重命名嵌套结构?

How to ask SWIG to rename nested structures differently?

假设我有一个 example.h 文件,其中包含以下内容:

struct foo_bar {
  int x;
};

struct foo {
  struct {
    int y;
  } bar;
};

example.i 以及以下内容:

%module example
%{
#include "example.h"
%}
%include "example.h"

现在,当我生成 SWIG 包装器时,SWIG 定义了一个新结构 foo_bar 来访问 foo 中嵌套的 bar 结构(也是 mentioned in the documentation)。然而,这导致 foo_bar 结构被复制并且编译失败。

那么,当 SWIG 创建自定义结构以访问 foo 的嵌套结构时,我如何要求 SWIG 使用 foo2,以便 foo 的所有嵌套结构都像 foo2_bar?我试过 %rename 但它只重命名包装函数,而不是 SWIG 创建的用于访问嵌套结构的自定义结构。

您可以使用高级 SWIG 重命名运算符有选择地仅重命名嵌套的 classes,例如:

%rename("nestedprefix%s", %$isnested) "";

将在任何嵌套类型的名称前添加'nestedprefix'。

您还可以使用正则表达式和全名匹配将 struct foo { struct bar {};}; 转换为 foo_bar:

%rename("%(regex:/.*?(::)?([^:]*)(::)?([^:]+)/\2_\4/)s", %$isnested, fullname=1) "";

(正则表达式可能需要一些调整以匹配所有我没有想到的奇怪情况)。

对于您使用匿名内部 class 展示的特定案例,您可以执行以下操作:

%module test

%rename("%s_inner", %$isnested, match$name="foo_bar") "";

%inline %{
struct foo_bar {};

struct foo {
  struct {
    int x;
  } bar;
};
%}

这只会重命名嵌套的 class,否则将被称为 foo_bar,而不是原始的 foo_bar

或者:

%rename("%s_inner", %$isnested, %$classname="foo") "";

将内部 class 与名为 foo 的父 class 匹配。

目前,我正在使用 /\bfoo\b/replace 对整个 C 源代码进行 find foo2