Thread overview
Mangling template
May 06, 2021
Wusiki jeronii
May 07, 2021
evilrat
May 07, 2021
Wusiki jeronii
May 07, 2021
evilrat
May 07, 2021
Wusiki jeronii
May 07, 2021
Wusiki jeronii
May 07, 2021
Wusiki jeronii
May 07, 2021
Wusiki jeronii
May 06, 2021

I wanna import a template function from .so lib. .so is written in D.

T abcd(T)(T a)
{
    return a;
}

........

writeln(abcd!int.mangleof);
auto a = mangle!(typeof(abcd!int))("dll.abcd");
writeln(a);

Output:
_D3dll__T4abcdTiZQiFNaNbNiNfiZi
_D3dll4abcdFNaNbNiNfiZi

Demangled:
pure nothrow @nogc @safe int dll.abcd!(int).abcd(int)
pure nothrow @nogc @safe int dll.abcd(int)

How to pass the template part to the mangle template? Is it possible at all to import a template function?

May 07, 2021

On Thursday, 6 May 2021 at 22:03:36 UTC, Wusiki jeronii wrote:

>

I wanna import a template function from .so lib. .so is written in D.

T abcd(T)(T a)
{
    return a;
}

........

writeln(abcd!int.mangleof);
auto a = mangle!(typeof(abcd!int))("dll.abcd");
writeln(a);

Output:
_D3dll__T4abcdTiZQiFNaNbNiNfiZi
_D3dll4abcdFNaNbNiNfiZi

Demangled:
pure nothrow @nogc @safe int dll.abcd!(int).abcd(int)
pure nothrow @nogc @safe int dll.abcd(int)

How to pass the template part to the mangle template? Is it possible at all to import a template function?

Template parameters is compile time construct, compiler only emits code for template instances and not the template itself, so template declaration is simply does not exist in compiled code.

Templates ends up as regular functions, the real deal is getting that name to load from .so, it is possible to load it with ldsym or any other mechanism.

You can probably adapt mangle function from std library by copying its implementation and rework it to make regular function that combines everything using strings. That will take quite some time and effort though.

https://dlang.org/phobos/core_demangle.html#.mangle

Or, you can just apply some mixin magic locally to construct some kind of interface tables with mapping from regular template name that will give you function pointer for specific instance.

May 07, 2021

On Friday, 7 May 2021 at 05:58:50 UTC, evilrat wrote:

>

On Thursday, 6 May 2021 at 22:03:36 UTC, Wusiki jeronii wrote:

Template parameters is compile time construct, compiler only emits code for template instances and not the template itself, so template declaration is simply does not exist in compiled code.

Templates ends up as regular functions, the real deal is getting that name to load from .so, it is possible to load it with ldsym or any other mechanism.

You can probably adapt mangle function from std library by copying its implementation and rework it to make regular function that combines everything using strings. That will take quite some time and effort though.

https://dlang.org/phobos/core_demangle.html#.mangle

Or, you can just apply some mixin magic locally to construct some kind of interface tables with mapping from regular template name that will give you function pointer for specific instance.

I understand that. Finally, I've got the right reference to functions.
Library:

    template test(T)
    {
        pragma(mangle, mangleFunc!(T function(T))("dll.test")) T test(T a)
        {
            return a;
        }
    }

Library loader:

    template abcd(T)
    {
        T function(T) abcd;
    }

    static this()
    {
        libdll = Library("libs/libdll.so");
        template abcd(T)
        {
            T function(T) abcd = cast(T function(T)) libdll.loadSymbol!(T function(T))("dll.test");
        }
        writeln(abcd!int(9));
    }

static ~this()
{

        version (Windows)
            Runtime.unloadLibrary(libdll.handle);
        else
            dlclose(libdll.handle);
        libdll.handle = null;
    }

I get the error:
Error: static variable libdll cannot be read at compile time.

How to redefine template? Need to point all functions by type manually without a template?

May 07, 2021

On Friday, 7 May 2021 at 06:17:32 UTC, Wusiki jeronii wrote:

>

I get the error:
Error: static variable libdll cannot be read at compile time.

Check how "libdll" and "Library" is defined, this error usually means you are forcing it to CTFE by reading or assigning it to enum, class member initializer, or any other compile time stuff.

>

How to redefine template? Need to point all functions by type manually without a template?

What do you mean by redefine template?

May 07, 2021

On Friday, 7 May 2021 at 07:36:40 UTC, evilrat wrote:

>

On Friday, 7 May 2021 at 06:17:32 UTC, Wusiki jeronii wrote:

>

I get the error:
Error: static variable libdll cannot be read at compile time.

Check how "libdll" and "Library" is defined, this error usually means you are forcing it to CTFE by reading or assigning it to enum, class member initializer, or any other compile time stuff.

>

How to redefine template? Need to point all functions by type manually without a template?

What do you mean by redefine template?

Solved.

Library libdll;
T abcd(T)(T a)
{
    T function(T) fun = cast(T function(T)) libdll.loadSymbol!(
            T function(T))("dll.test");
    return fun(a);
}

static this()
{
    libdll = Library("libs/libdll.so");
    writeln(abcd!float(6.5f));
}

Thanks for your responses.

May 07, 2021

On Friday, 7 May 2021 at 07:36:40 UTC, evilrat wrote:

>

On Friday, 7 May 2021 at 06:17:32 UTC, Wusiki jeronii wrote:

>

I get the error:
Error: static variable libdll cannot be read at compile time.

Check how "libdll" and "Library" is defined, this error usually means you are forcing it to CTFE by reading or assigning it to enum, class member initializer, or any other compile time stuff.

>

How to redefine template? Need to point all functions by type manually without a template?

What do you mean by redefine template?

Solved.

Library libdll;
T abcd(T)(T a)
{
    T function(T) fun = cast(T function(T)) libdll.loadSymbol!(
            T function(T))("dll.test");
    return fun(a);
}

static this()
{
    libdll = Library("libs/libdll.so");
    writeln(abcd!float(6.5f));
}

Thanks for your responses.

May 07, 2021

On Friday, 7 May 2021 at 08:24:15 UTC, Wusiki jeronii wrote:

>

On Friday, 7 May 2021 at 07:36:40 UTC, evilrat wrote:

>

On Friday, 7 May 2021 at 06:17:32 UTC, Wusiki jeronii wrote:

>

I get the error:
Error: static variable libdll cannot be read at compile time.

Check how "libdll" and "Library" is defined, this error usually means you are forcing it to CTFE by reading or assigning it to enum, class member initializer, or any other compile time stuff.

>

How to redefine template? Need to point all functions by type manually without a template?

What do you mean by redefine template?

Solved.

Library libdll;
T abcd(T)(T a)
{
    T function(T) fun = cast(T function(T)) libdll.loadSymbol!(
            T function(T))("dll.test");
    return fun(a);
}

static this()
{
    libdll = Library("libs/libdll.so");
    writeln(abcd!float(6.5f));
}

Thanks for your responses.

New problem.
I am getting the error:

object.Exception@source/app.d(67): libs/libdll.so: undefined symbol: _D3dll4testFfZf

But if I will address in my DLL in any place to my template the error disappears.
Example:
Compiles

shared static this()
{
    writeln("libdll.so is loaded");
    writeln(test!float(7));
}

Does not compiles

shared static this()
{
    writeln("libdll.so is loaded");
    //writeln(test!float(7));
}

It isn't a problem with pragma. 'cos even without pragma (by _D3dll__T4testHTfZQjFNaNbNiNffZf) it doesn't work if I will not point to explicit type.
Another example:
I will declare just another function in the DLL source file.
Works

string fff()
{
    auto h = test!float(8);
    return "";
}

Doesn't work (same error with undefined symbol)

string fff(T)()
{
    auto h = test!T(8);
    return "";
}

Looks like if I won't explicitly act need template it will not unload as a symbol after building. But it's the library!!! Library of functions. I don't need to address functions in the source code.
So with functions (non-template), there isn't such a problem.

May 07, 2021

On Friday, 7 May 2021 at 17:37:32 UTC, Wusiki jeronii wrote:

>

On Friday, 7 May 2021 at 08:24:15 UTC, Wusiki jeronii wrote:

>

[...]

New problem.
I am getting the error:

object.Exception@source/app.d(67): libs/libdll.so: undefined symbol: _D3dll4testFfZf

[...]

Oooh. I got explanation at https://stackoverflow.com/questions/67421294/how-to-get-template-function-from-so-dll/67430130#67430130