【问题标题】:How to expose array of C strings char[M][N] in SWIG?如何在 SWIG 中公开 C 字符串数组 char[M][N]?
【发布时间】:2014-02-07 19:16:11
【问题描述】:

我有一个像这样的传统 C/C++ 结构(还有许多其他成员):

struct S {
  char one_name[MAX_LEN];
  char names[N_NAMES][MAX_LEN];
}

以及创建这些的 C 函数:

S *get_S(...)

我想通过 swig 导出 S 和名称,以便我可以在 python 中执行此操作:

s = MyModule.get_S()
print s.one_name # I have this working
print s.names[1] # should print the 2nd string, this is harder

我认为我需要某种类型映射,但我是新来的 swig。我可以使用 SWIG/python array inside structure 中的 Wrapped_array 模板执行 one_name,但我不确定如何将其扩展到字符串数组。我只需要从 python 中读取这些字符串(如上所述),而不是编写它们。我可以用访问器来做,所以 python 看起来像:

print s.get_name(i) # prints the ith name

但我更喜欢数组接口,因为它类似于 C 接口。

【问题讨论】:

  • 您是否有理由不使用 std::string? SWIG 会自动处理它。
  • @Schollii:我无法更改要包装的底层接口;这是古老的C代码。如果需要,我可以编写一个访问器函数,而不是直接公开字符串数组。我只是希望我能以 Python 的方式公开它,但尽可能与现有的 C 代码相似,以便用户熟悉它。

标签: python swig


【解决方案1】:

如果你只需要从 python 中读取它们,那么一个快速的解决方案是创建一个使用std::strings 的适配器类和一个适配器函数。这一切都通过 %inline 进入 .i 文件,您还需要 %rename 并且可能需要 %ignore。例如,

%ignore(S)
%rename(S) Swrap
%rename(get_S) get_SWrap
%newobject get_Swrap

%inline %{
struct Swrap
{
     inline Swrap(S* s): one_name(s.one_name) 
     {
          for (i=0; i<N_NAMES; ++i)
               names[i] = s.names[i];
          // no longer need s:
          delete s; 
     }

     string one_name;
     string names[N_NAMES];    
};

Swrap* get_Swrap() {
    return new Swrap(get_S());
}
%}

【讨论】:

  • 如果我理解您的解决方案,我想我并不清楚。当我说我只需要读取字符串时,我的意思是从 python 读取(我的 S 结构是在 C 端创建和管理的)。您的解决方案适用于在 C 端只读的字符串。也许有一个类似的想法可以以另一种方式工作,我会考虑更多。我了解到 Swig 有很多钩子可以替换任何东西。
  • 在您的代码中,您创建一个 S,然后修改其数据成员。您是否需要做更多的事情,例如将其传递给修改数据成员的导出 C++ 函数?您能否用您想从 python 执行的操作示例扩展您的问题,这将有很大帮助。
  • 我更新了问题,希望现在更有意义。
  • 我更新了我的答案。请注意,%extend 非常强大,可能会使这更加简单。
  • @garyo 看起来你接受了,但没有投票;还是不清楚,还是其他原因?
猜你喜欢
  • 2013-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
  • 2012-10-28
  • 2015-08-01
相关资源
最近更新 更多