【问题标题】:How to get template function from so/dll?如何从 so/dll 中获取模板函数?
【发布时间】:2021-05-06 15:28:00
【问题描述】:

如何从so/dll中获取模板函数? 我试过了:

Library libdll;
T abc(T)();
static this()
{
    libdll = Library("libs/libdll.so");
    abc = cast(typeof(abc)) libdll.loadSymbol!(typeof(abc))("dll.abc");
    //abc();
}

但随后abc的类型被确定为void。 我在编译中遇到错误:

Error: expression `cast(void)dlsym(this.handle, toStringz(cast(const(char)[])m))` is `void` and has no value

m - 是dll.abc 的错名。

【问题讨论】:

    标签: function templates dll shared-libraries d


    【解决方案1】:

    D 中的模板是仅编译时的构造,在 sos/dll 中不存在。特定实例以 so 结尾,但仅限于那些在此处使用的实例。也就是说,如果你在so/dll中有这段代码:

    module dll;
    
    T abc(T)() {
        T result = void;
        return result;
    }
    
    void use() {
        auto var = abc!int();
    }
    

    您应该能够从 so/dll 中获取 dll.abc!int.abc(错位名称 _D3dll__T3abcTiZQhFNaNbNiNfZi)。

    如果你想用其他类型调用abc,比如abc!string,那你就不走运了——代码根本不存在。

    这涵盖了可行性。如果你只想要一个你知道已经实例化的特定实例,这里还有另一个问题,那就是使用typeof(abc)。同样,abc 是编译时的东西,没有类型。令人困惑的是,编译器会为typeof(abc) 返回void,并给出错误消息is `void` and has no value

    abc!int 是一个函数,并且确实有一个类型 (pure nothrow @nogc @safe int()),所以使用它应该可以工作。如上所示,名称将是dll.abc!int.abc(它是eponymous template,因此是重复名称)。

    TL;DR:如果您想要模板的特定实例,并且已在 so/dll 中实例化,则此代码应该可以工作(但尚未经过测试):

    Library libdll;
    T abc(T)();
    static this()
    {
        libdll = Library("libs/libdll.so");
        abc = cast(typeof(abc!int)) libdll.loadSymbol!(typeof(abc!int))("dll.abc!int.abc");
        abc();
    }
    

    【讨论】:

    • 我用你的回答做了一个具体的例子来展示如何使用它:wfr.moe/c6m1Hn/dll-sample.d
    • 非常感谢。今天我在我的代码中结交了函数和模板,但我遇到了你在开始时解释过的问题。 T 问题。如果我不在 DLL 源代码中显式处理模板,则不存在不同的类型。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 2014-02-07
    • 2019-06-02
    • 2021-10-28
    相关资源
    最近更新 更多