2011-06-21 42 views
4

我正在研究一個現有C庫的D綁定,我有一堆函數定義和一堆綁定。例如:在D中混合具有可變數量的字符串參數的混合?

// Functions 
void function(int) funcA; 
long function() funcB; 
bool function(bool) funcC; 
char function(string) funcD; 
// etc... 

// Bindings 
if(!presentInLibrary("func")) return false; 
if(!bindFunction(funcA, "funcA")) return false; 
if(!bindFunction(funcB, "funcB")) return false; 
if(!bindFunction(funcC, "funcC")) return false; 
if(!bindFunction(funcD, "funcD")) return false; 
// etc... 

該模型與Derelict如何處理OpenGL擴展加載非常相似。但是,這看起來像是很多多餘的輸入。我真的很想要一種方式來表達上面的「綁定」部分,如下所示:

BINDGROUP("func", "funcA", "funcB", "funcC", "funcD", ...); // Name of function group, then variable list of function names. 

這是可以使用mixins完成的事情嗎?

回答

5

我用這個當我正做動態加載,雖然它沒有回答你的問題,你可能能夠適應它:

void function() a; 
int function(int) b; 
void function(string) c; 

string bindFunctions(string[] funcs...) 
{ 
    string ret; 
    foreach (func; funcs) 
    { 
     ret ~= func ~ ` = cast(typeof(` ~ func ~ `))lib.getSymbol("` ~ func ~ `");`; 
    } 
    return ret; 
} 
mixin(bindFunctions("a", "b", "c")); 

這裏bindFunctions("a", "b", "c")返回一個字符串,看起來像:

a = cast(typeof(a))lib.getSymbol("a"); 
b = cast(typeof(b))lib.getSymbol("b"); 
c = cast(typeof(c))lib.getSymbol("c"); 

lib.getSymbol()返回從dl_open()指針等希望這有助於。

+0

我不得不嘲笑它,但我認爲你應該可以在不使用字符串混合的情況下使用靜態foreach機能的研究。您可能需要使用模板混合來從正確的作用域綁定事物。 – BCS

4

我假設你的意思是string mixins?你可以只作簡單直接的使用D的可變參數的語法:

string BINDGROUP(string functionGroup, string[] functions...) 
{ 
    // ... 
} 

mixin(BINDGROUP("func", "funcA", "funcB", "funcC", "funcD")); 
+0

我的印象是,這是行不通的,因爲字符串必須在編譯時被知道,並且有一個字符串變量可以打破這種情況。如果情況並非如此,我肯定會這樣做! (另外,是的,我的意思是string mixins,謝謝你的澄清)。 –

+0

@標記編譯器將嘗試在編譯時計算弱純函數,如果結果需要完成編譯(使用'enum'或'mixin')並在無法計算時拋出錯誤。除了可變參數(以及一般的模板參數)在實例化時在編譯時被擴展 –

4

我相信這是你在找什麼

template BINDGROUP(string group,T...){ 
    alias BINDGROUP presentInLibrary("func") && BINDGROUPFUNCS!(T); 
} 

template BINDGROUPFUNCS(T...){ 
    static if(T.length)alias BINDGROUPFUNCS true; // all is successful 
    else alias BINDGROUPFUNCS bindFunction(mixin(T), T) && BINDGROUPFuncts!(T[1..$]); 
} 

我在這裏使用遞歸模板聲明,你也可以做這與foreach循環