www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Mangling template

reply Wusiki jeronii <wusikijeronii gmail.com> writes:
I wanna import a template function from .so lib. .so is written 
in D.
```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 06
parent reply evilrat <evilrat666 gmail.com> writes:
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.
 ```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 06
parent reply Wusiki jeronii <wusikijeronii gmail.com> writes:
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: ```d template test(T) { pragma(mangle, mangleFunc!(T function(T))("dll.test")) T test(T a) { return a; } } ``` Library loader: ```d 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 06
parent reply evilrat <evilrat666 gmail.com> writes:
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
next sibling parent Wusiki jeronii <wusikijeronii gmail.com> writes:
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. ```d 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
prev sibling parent reply Wusiki jeronii <wusikijeronii gmail.com> writes:
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. ```d 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
parent reply Wusiki jeronii <wusikijeronii gmail.com> writes:
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. ```d 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: ```shell 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 ```d shared static this() { writeln("libdll.so is loaded"); writeln(test!float(7)); } ``` Does not compiles ```d 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 ```d string fff() { auto h = test!float(8); return ""; } ``` Doesn't work (same error with undefined symbol) ```d 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
parent Wusiki jeronii <wusikijeronii gmail.com> writes:
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: ```shell 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
May 07