是否可以在内联函数中指定 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 东西自动编写包装器。
我有一个函数类型 alias Func = extern (C) void function();
和一个接收 Func 作为参数的函数 extern (C) void whatever(Func);
。调用 whatever
?
例如:
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 东西自动编写包装器。