Pass delegates to external C functions in D

馋奶兔 提交于 2019-12-10 13:38:46

问题


How do I pass a delegate to an external C function taking a function pointer, in D?


回答1:


Let me cross post what I said on the newsgroup:

How do I pass a delegate to an external C function taking a function pointer?

You can't do it directly in general, unless you can modify the C function, then you can hack around it, but a delegate and a regular function pointer are pretty different animals.

But perhaps you can magic hack it. Observe:

// a C function that needs a plain function
extern(C) void test(void function() f) {
    // pretend this is implemented in C
    f();
}

// just create a random delegate
void delegate() foo(int a) {
    return { import std.stdio; writeln(a); };
}

// what we want to work
void main() {
    auto dg = foo(10);
    dg(); // works

    //test(dg); // won't work
    test(bindDelegate(dg)); // we want this
}

// transform delegate into pointer..
import std.traits;
auto bindDelegate(T, string file = __FILE__, size_t line = __LINE__)(T t) if(isDelegate!T) {
    static T dg;

    dg = t;

    extern(C)
    static ReturnType!T func(ParameterTypeTuple!T args) {
            return dg(args);
    }

    return &func;
}

What bindDelegate does is create a special static variable and function for that specific call. It is as if we wrote a separate function and global to hold it.

The __FILE__, __LINE__ things are a filthy hack to make it instantiate a separate variable+function pair for different lines so the global variable holding the delegate won't be so easily overwritten.



来源:https://stackoverflow.com/questions/22845175/pass-delegates-to-external-c-functions-in-d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!