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

C# SWIG vector<string> to string[]

本文关键字:字符串 gt string SWIG lt 向量      更新时间:2023-10-16

给定c++方法,如

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

我怎样才能让SWIG像这样暴露给c#

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

我意识到很多人都问过vector<string>和SWIG,但我还没有看到任何解决与string[]转换的问题。每个人都提到使用SWIG模板,就像这样

%template(StringVector) vector<string>;

但这只是创建了一个数据类型,调用者必须知道如何手动封送。理想情况下,调用者只需要处理string[],让SWIG层解决它。

我怎么能简单地使用string[]在c#,但有它变成vector<string>在c++ ?

一种方法是将隐式强制转换添加到swig生成的StringVector中,这样它就能够将自己强制转换到/从string[]中。

我试着通过typemap这样做,但不能使它工作。然而,它可以用部分类来完成。

它看起来像这样。在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[],因此这并不重要。