Reputation: 6563
Given C++ methods like
std::vector< std::string > getFoo();
void setFoo( const std::vector< std::string > &foo);
How can I get SWIG to expose it like this to C#
string[] getFoo();
setFoo(string[] foo);
I realize that lots of people have asked about vector<string>
and SWIG, but I haven't seen anything addressing the conversion to/from string[]
. Everyone mentions using the SWIG templates, like this
%template(StringVector) vector<string>;
But that just creates a datatype that callers will have to know to marshal manually. Ideally, a caller would only have to deal with string[]
and let the SWIG layer figure it out.
How can I simply use string[]
in C# but have it turn into vector<string>
in C++?
Upvotes: 2
Views: 3080
Reputation: 6563
One approach could be to add implicit casting to the SWIG-generated StringVector, so that it would be able to cast itself to/from string[]
.
I tried doing this via a typemap
, but couldn't make it work. However, it can be done with partial classes.
It looks something like this. In 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 >;
Then in C#, create a partial version of 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;
}
}
This allows you to write C# code that looks like this:
string[] foo= mymodule.getFoo();
string[] thenewfoo= { "one", "two", "three" };
mymodule.setFoo(thenewfoo);
It's still StringVector in the C# method signatures, but since the client coder can just use string[]
it doesn't really matter.
Upvotes: 3