3

私はかなりのボイラープレートで関数をエクスポートしており、文字列のミックスインを使用して、混乱を隠して砂糖を加えようとしています。問題は、無名関数を文字列 mixin に渡す方法がわからないことです。可能であれば、関数を文字列として記述することは避けたいと思います。

// The function that the anonymous function below ultimately gets passed to.
char* magic(F...)(string function(F) func) { ... }

string genDcode(string name, alias func)() {
    return xformat(q{
        extern(C) export char* %s(int blah) {
            // What would I inject into the string in place of 'func'
            // in order to call the 'func' passed into the template?
            return magic(func);
        }
    }, name);
}

// Calls a function to generate code to mix into the global scope.
// The anonymous function must allow abritrary parameters.
mixin(genDcode!("funcName", function(string foo, float bar) {
    return "Herpderp";
}));

もちろん、これは全体像ではなく、ボイラープレートのほとんどが削除されていますが、問題を示すには十分です。関数ポインターを int として注入し、呼び出し可能な型にキャストすることを考えましたが、当然のことながら、関数ポインターは実行時にしか取得できません。

関数の受け渡しの問題を解決する mixin テンプレートを試しましたが、リンカーはそのような mixin から生成されたエクスポート関数を見つけることができないようです。追加の修飾子がいくつかあるようで、DEF ファイルではドットを使用できません。

4

1 に答える 1

1

古い質問ですが、比較的新しい機能がそれを解決するのに役立つかもしれません: D には、リンカーに特定の名前を強制するために mixin テンプレート内に配置できる pragma(mangle) があります。

mixin template genDcode(string name, alias func) {
          // pragma mangle is seen by the linker instead of the name...
        pragma(mangle, name) extern(C) export char* impl(int blah) {
            return magic(func);
        }
}

char* magic(F...)(string function(F) func) { return null; }

mixin genDcode!("funcName", function(string foo, float bar) {
     return "Herpderp";
});
于 2013-11-04T22:27:15.643 に答える