2014-07-27 30 views
0

比方說,我有一個任意的非平凡類型A,我可以寫typemaps。特別是,假設我知道如何將std::strings轉換爲A,並且我將目標語言字符串的類型映射到A。我輸入stl_vector.i%template(AVector) std::vector<A>;element typemap + stl_vector.i typemap + ??? - >包裹功能取電子列表

什麼是SWIG中最快/最簡單(甚至是'正確')的動作過程,其功能包裝爲void func(const std::vector<A>& vals),其中目標語言端的預期輸入是字符串列表(例如Python中的['a', 'qqq'])?除非我錯了,否則它不會顯示Just Work™(特別是,在生成的封裝代碼中沒有任何地方可以看到A的類型圖代碼)。

如果你需要需要一個特定的目標語言來回答,我們假設它是Python。我寧願能做到這在一般情況下,雖然...

回答

0

假設我們有一個頭文件看起來像:

#ifndef TEST_H 
#define TEST_H 

#include <iostream> 
#include <functional> 
#include <iterator> 

struct A { 
    A(const std::string& v) : val(v) {} 
    A(const A&) = default; 
    A() = default; 
    std::string val; 
}; 

inline std::ostream& operator<<(std::ostream& in, const A& o) { 
    return in << o.val; 
} 

inline void run(const std::vector<A>& in) { 
    std::copy(in.begin(), in.end(), std::ostream_iterator<A>(std::cout, "\n")); 
}  
#endif 

我們希望把它包起來,使得run可以被稱爲與字符串列表或std::vector<A>交替。

鑑於語言不可知性是一個陳述的目標,實現這一目標的最好方法是引入更多的C++,以幫助進行某些類型轉換和重載。

我們可以初步包住頭文件簡單的東西,如:

%module test 

%include <std_vector.i> 
%include <std_string.i> 

%{ 
#include "test.h" 
%} 

%template(AVec) std::vector<A>; 

%include "test.h" 

,然後足以運行我們的Python測試用例上半年:

import test 

test.A("") 

v1=test.AVec(2,test.A("testing")) 
print type(v1) 
test.run(v1) 

# Here onwards needs some more work though... 
v2=["hello", "world", "isn't", "this", "fun"] 
print type(v2) 
test.run(v2) 

要開始工作在這個測試案例的後半部分,我們需要調整SWIG接口。我將通過添加一個函數來實現這個功能,這個函數在包裝器內部以及一個利用SWIG默認的std::vector<std::string>的默認類型映射的過載。

通過添加:

%{ 
// Some glue to trivially convert types 
std::vector<A> convert(const std::vector<std::string>& in) { 
    std::vector<A> ret; 
    std::copy(in.begin(), in.end(), std::back_inserter(ret)); 
    return ret; 
} 
%} 

%inline %{ 
// An overload. 
void run(const std::vector<std::string>& in) { 
    run(convert(in)); 
} 
%} 

爲我們添加了作品所提供的目標語言超載初始SWIG接口端具有的std::vector合適的理解。 (大部分我檢查似乎)。

隨着我測試SWIG的版本,運行SWIG本身時出現警告,給出了有關鏡像過載的(僞)警告。這個警告似乎是不正確的,因爲生成的代碼確實根據給定的參數選擇了正確的重載。

在界面文件中使用與%inline一起添加的過載是迄今爲止最快/最簡單的方式來啓動和運行。當然,它要求複製/轉換開銷根據功能手動寫入重載。用typemap做它只需要編寫一個單一的類型圖,但是要以獨立於目標語言的方式很難做到。