我有一个函数类型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)
,因此模板也可以免费获取它。
请注意,我还没有尝试运行这个,也许它可以编译,但在运行时做了错误的事情。
但是,我不认为零参数内联函数有任何类似的技巧。
您可能还可以编写一个全局级模板来包装给定的函数并返回该函数。看哪:
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 的包装器)。
关于d - 是否可以在内联函数中指定 extern?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34504470/