C# SWIG 向量<字符串> 到字符串 []

Posted

技术标签:

【中文标题】C# SWIG 向量<字符串> 到字符串 []【英文标题】:C# SWIG vector<string> to string[] 【发布时间】:2013-02-28 22:37:29 【问题描述】:

给定 C++ 方法,例如

std::vector< std::string > getFoo();
void setFoo( const std::vector< std::string > &foo);

如何让 SWIG 像这样向 C# 公开它

string[] getFoo();
setFoo(string[] foo);

我意识到有很多关于 vector&lt;string&gt; 和 SWIG 的 people have asked,但我还没有看到任何解决与 string[] 之间的转换的内容。每个人都提到使用 SWIG 模板,像这样

%template(StringVector) vector<string>;

但这只会创建调用者必须知道才能手动编组的数据类型。理想情况下,调用者只需处理 string[] 并让 SWIG 层解决。

如何在 C# 中简单地使用 string[] 而在 C++ 中将其转换为 vector&lt;string&gt;

【问题讨论】:

【参考方案1】:

一种方法是将implicit casting 添加到 SWIG 生成的 StringVector,以便它能够将自己投射到 string[] 或从 string[] 投射。

我尝试通过typemap 执行此操作,但无法成功。但是,可以使用partial classes 完成。

看起来像这样。在 SWIG 中,

%include std_vector.i
%include std_string.i

/* allow partial c# classes */
%typemap(csclassmodifiers) SWIGTYPE "public partial class"

/* generate template around vector<string> */
%template(StringVector) std::vector< std::string >;

然后在 C# 中,创建 StringVector 的部分版本:

public partial class StringVector: IDisposable, System.Collections.IEnumerable
#if !SWIG_DOTNET_1
    , System.Collections.Generic.IList<string>
#endif

    // cast from C# string array
    public static implicit operator StringVector(string[] inVal) 
        var outVal= new StringVector();
        foreach (string element in inVal) 
            outVal.Add(element);
        
        return outVal;
    

    // cast to C# string array
    public static implicit operator string[](StringVector inVal) 
        var outVal= new string[inVal.Count];
        inVal.CopyTo(outVal);
        return outVal;
    

这允许您编写如下所示的 C# 代码:

string[] foo= mymodule.getFoo();
string[] thenewfoo=  "one", "two", "three" ;
mymodule.setFoo(thenewfoo);

它仍然是 C# 方法签名中的 StringVector,但由于客户端编码器可以使用 string[],这并不重要。

【讨论】:

我觉得这是为了接口兼容而牺牲了不少效率。话又说回来,我可能会在紧要关头想出同样的主意。 +1 我认为大多数时候使用 SWIG 界面的人真的想要string[],所以无论如何他们都会手动转换它。无论如何,这种方法的一个好处是,如果效率很重要,您可以直接使用 StringVector。 另外,请注意,这确实只适用于编译时。您不能将 StringVector 传递给任何泛型方法,并且仍然期望它进行用户定义的转换(没有泛型类型约束)。虽然,C#4.0' dynamic 可能能够成功(需要检查)。 我们可以将 StringVector 类保留在内部吗? 最好在方法签名中看到IList&lt;string&gt;而不是StringVector

以上是关于C# SWIG 向量<字符串> 到字符串 []的主要内容,如果未能解决你的问题,请参考以下文章

将字符串 (const char*) 从 C++ 传递到 C# 时,SWIG_csharp_string_callback 会导致内存泄漏

在 swig 上包装返回向量<T>

SWIG c++ 到 python:向量问题

使用 swig 类型映射从 c++ 方法返回向量<pair<int,int>> & 到 python 元组列表

在控制台中打印特殊字符 (C++/C#/SWIG)

从 SWIG 绑定中迭代返回的向量<pair<int,int>>