2013-02-28 89 views
2

鑑於C++的方法,如C#呷矢量<string>串[]

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

我怎樣才能得到痛飲揭露像這樣的C#

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

我知道很多people have askedvector<string>和SWIG,但是我還沒有看到任何解決string[]轉換的問題。每個人都提到了使用SWIG模板,這樣

%template(StringVector) vector<string>; 

但是,這僅僅是創建一個數據類型呼叫者必須知道手動元帥。理想情況下,來電者只需要處理string[]並讓SWIG層識別出來。

如何在C#中簡單地使用string[]但在C++中將它變成vector<string>

回答

2

一種方法可能是將implicit casting添加到SWIG生成的StringVector,以便它能夠將自己投射到string[] /中。

我試圖通過typemap這樣做,但無法使其工作。但是,可以使用partial classes完成。

它看起來像這樣。在痛飲,

%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); 

它仍然StringVector在C#方法簽名中,但由於客戶端編碼器只能使用string[],所以它並不重要。

+0

我覺得這是爲了接口兼容性而犧牲相當多的效率。然後,再次,我可能會捏起一個相同的想法。 +1 – sehe 2013-02-28 22:40:46

+0

我認爲大多數時候使用SWIG接口的人真的都想要'string []',所以他們會手動轉換它。無論如何,這種方法的一個好處是,如果效率非常重要,你可以直接使用StringVector。 – paleozogt 2013-02-28 22:44:03

+0

另外,請注意,這隻會在編譯時才起作用。您無法將StringVector傳遞給任何泛型方法,並且仍然期望它執行用戶定義的轉換(對此沒有泛型類型約束)。雖然,C#4.0''dynamic'可能會把它拉下來(需要檢查)。 – sehe 2013-02-28 22:45:58