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

标签 d

我有一个函数类型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/

相关文章:

user-interface - D 的 GUI 库

null - 正确使用 NotNull

linker - 错误 42 : Symbol Undefined

d - vibe.d 的 Diet 模板中的别名是什么?

string - 在Flex/Bison中实现字符串插值

c++ - 如何内存映射一个巨大的矩阵?

exception - Phobos(和/或 Tango)有一组预定义的异常类型吗?

d - 将 dlang char/wchar 转换为 string/wstring

d - 在 D 中将成员函数作为模板参数传递

types - 将 Variant 转换为正确类型的正确方法是什么?