是否可以在内联函数中指定 extern?

Is it possible to specify extern in an inline function?

我有一个函数类型 alias Func = extern (C) void function(); 和一个接收 Func 作为参数的函数 extern (C) void whatever(Func);。调用 whatever?

时是否可以使用 extern (C) 链接创建内联函数

例如:

Func x = function() {}
whatever(x); //Works
whatever(function() {}); // Compilation error, invalid linkage

是...但前提是 Func 接受一个参数并且您使用 out 定义内联函数并指定该参数的类型。

extern(C) alias Func = void function(int);

extern(C)
void foo(Func f) {

}

void main() {
        Func x = function(a) {};
        pragma(msg, typeof(x));
        foo(x);

        foo(function(a) {});
}

行得通。我试过的其他任何东西都没有,并查看 dlang.org 处的语法,它并没有说它允许在内联函数上使用 extern 字,所以我认为我没有遗漏任何东西(尽管我总是有可能)。

第一个参数起作用的原因是当你没有在函数文字中指定参数类型时,编译器将其设为 模板 文字,自动用类型实例化接收函数期望您传递它。

由于接收函数需要 extern(C),模板也免费获得它。

请注意,我还没有尝试过运行这个,也许它编译但在运行时做错了事。

但是,我认为 zero-argument 内联函数没有任何类似的技巧。


您可能还可以编写一个全局级别的模板来包装您的给定函数和 returns。看:

extern(C) alias Func = void function();

extern(C)
void foo(Func f) {

}

template wrap(alias f) {
    extern(C) void wrapped() {
        // you can also put stuff like try/catch
        // in here if you like so exceptions don't
        // accidentally pass through the C function
        return f();
    }
    Func wrap() {
        return &wrapped;
    }
}

void main() {
        Func x = function() {};
        pragma(msg, typeof(x));
        foo(x);

        foo(wrap!(function() {}));
}

包装器解决方案也有优点和缺点,比如能够添加 try/catch 或在普通 D 函数上使用,但缺点是您需要实际使用包装器并编写它(尽管您可以使用 std.traits 东西自动编写包装器。