www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Exporting template function instances to C

reply data pulverizer <data.pulverizer gmail.com> writes:
I have noticed that the following will not successfully export 
`dmult` and `fmult` to C:

```
extern (C) nothrow  nogc  system:
pragma(LDC_no_moduleinfo);
T mult(T)(T x, T y)
{
     return x*y;
}
alias mult!double dmult;
alias mult!float fmult;
```

but this will

```
extern (C) nothrow  nogc  system:
pragma(LDC_no_moduleinfo);
T mult(T)(T x, T y)
{
     return x*y;
}

double dmult(double x, double y)
{
	return mult(x, y);
}

float fmult(float x, float y)
{
	return mult(x, y);
}
```

Why is that?
Mar 23
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 23 March 2017 at 16:28:18 UTC, data pulverizer wrote:
 alias mult!double dmult;
 alias mult!float fmult;
Those are just aliases in the D compiler, they don't actually exist in the object file for C to use like regular functions. Templates need to actually be *used* to be instantiated for export, and aliases make them easier to use, but don't actually use them yet.
 Why is that?
Mar 23
parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Thursday, 23 March 2017 at 16:38:02 UTC, Adam D. Ruppe wrote:
 On Thursday, 23 March 2017 at 16:28:18 UTC, data pulverizer 
 wrote:
 alias mult!double dmult;
 alias mult!float fmult;
Those are just aliases in the D compiler, they don't actually exist in the object file for C to use like regular functions. Templates need to actually be *used* to be instantiated for export, and aliases make them easier to use, but don't actually use them yet.
 Why is that?
Thanks. Is there a less ham-handed way of exporting them other than wrapping them in functions as I have?
Mar 23
parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Thu, Mar 23, 2017 at 05:29:22PM +0000, data pulverizer via
Digitalmars-d-learn wrote:
 On Thursday, 23 March 2017 at 16:38:02 UTC, Adam D. Ruppe wrote:
 On Thursday, 23 March 2017 at 16:28:18 UTC, data pulverizer wrote:
 alias mult!double dmult;
 alias mult!float fmult;
Those are just aliases in the D compiler, they don't actually exist in the object file for C to use like regular functions. Templates need to actually be *used* to be instantiated for export, and aliases make them easier to use, but don't actually use them yet.
[...]
 
 Thanks. Is there a less ham-handed way of exporting them other than
 wrapping them in functions as I have?
Wrapping them in functions is probably the simplest way to call them from C. You *could*, I suppose, use their mangled names directly, then you wouldn't need a wrapper, but that would be rather difficult to use on the C end. On the D side, there's .mangleof that will tell you what mangled names to use, but if you're calling from C you don't have that luxury. T -- People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird. -- D. Knuth
Mar 23
parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Thursday, 23 March 2017 at 17:58:21 UTC, H. S. Teoh wrote:
 On Thu, Mar 23, 2017 at 05:29:22PM +0000, data pulverizer via
 
 Thanks. Is there a less ham-handed way of exporting them other 
 than wrapping them in functions as I have?
Wrapping them in functions is probably the simplest way to call them from C. You *could*, I suppose, use their mangled names directly, then you wouldn't need a wrapper, but that would be rather difficult to use on the C end. On the D side, there's .mangleof that will tell you what mangled names to use, but if you're calling from C you don't have that luxury. T
Thanks. Mangling sounds painful and scary, I think I'll stick to wrapping which sounds much less dangerous.
Mar 23
parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Thursday, 23 March 2017 at 19:46:43 UTC, data pulverizer wrote:
 On Thursday, 23 March 2017 at 17:58:21 UTC, H. S. Teoh wrote:
 On Thu, Mar 23, 2017 at 05:29:22PM +0000, data pulverizer via
 
 Thanks. Is there a less ham-handed way of exporting them 
 other than wrapping them in functions as I have?
Wrapping them in functions is probably the simplest way to call them from C. You *could*, I suppose, use their mangled names directly, then you wouldn't need a wrapper, but that would be rather difficult to use on the C end. On the D side, there's .mangleof that will tell you what mangled names to use, but if you're calling from C you don't have that luxury. T
Thanks. Mangling sounds painful and scary, I think I'll stick to wrapping which sounds much less dangerous.
There's nothing scary or dangerous about it. It happens automatically to allow overloads and templates so that you get a unique symbol foreach version (unless you use extern(C), extern(C++) or pragma mangle). C++,Java and any other compiled language that has overloads does mangling. Heck, you can even do it in C with __attribute__((overloadable)) (at least with clang), it just transparently mangles (just as in D)the name as whatever C++ would mangle it as. So instead of doing T mult(T)(T x, T y) { return x*y; } doing something like template mult(T) { extern(C++) T mult(T x, T y) { return x*y; } } in D, and then in C (noting that you have to declare the name and signature anyway) __attribute__((overloadable)) float mult(float,float); __attribute__((overloadable)) double mult(double, double); which I think is the least painful way of doing it. I seem to remember somewhere in phobos template Instantiate(alias a) { alias Instantiate = a; } to instantiate template, because you reference them from another symbol it somehow magically works. Used like Instantiate!(mult!float); // at module scope
Mar 23
parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Friday, 24 March 2017 at 01:00:31 UTC, Nicholas Wilson wrote:
 On Thursday, 23 March 2017 at 19:46:43 UTC, data pulverizer 
 wrote:
 On Thursday, 23 March 2017 at 17:58:21 UTC, H. S. Teoh wrote:
 On Thu, Mar 23, 2017 at 05:29:22PM +0000, data pulverizer via
 
 Thanks. Is there a less ham-handed way of exporting them 
 other than wrapping them in functions as I have?
Wrapping them in functions is probably the simplest way to call them from C. You *could*, I suppose, use their mangled names directly, then you wouldn't need a wrapper, but that would be rather difficult to use on the C end. On the D side, there's .mangleof that will tell you what mangled names to use, but if you're calling from C you don't have that luxury. T
Thanks. Mangling sounds painful and scary, I think I'll stick to wrapping which sounds much less dangerous.
There's nothing scary or dangerous about it. It happens automatically to allow overloads and templates so that you get a unique symbol foreach version (unless you use extern(C), extern(C++) or pragma mangle). C++,Java and any other compiled language that has overloads does mangling. Heck, you can even do it in C with __attribute__((overloadable)) (at least with clang), it just transparently mangles (just as in D)the name as whatever C++ would mangle it as. So instead of doing T mult(T)(T x, T y) { return x*y; } doing something like template mult(T) { extern(C++) T mult(T x, T y) { return x*y; } } in D, and then in C (noting that you have to declare the name and signature anyway) __attribute__((overloadable)) float mult(float,float); __attribute__((overloadable)) double mult(double, double); which I think is the least painful way of doing it. I seem to remember somewhere in phobos template Instantiate(alias a) { alias Instantiate = a; } to instantiate template, because you reference them from another symbol it somehow magically works. Used like Instantiate!(mult!float); // at module scope
Thanks a lot ... I was half joking playing with the name "mangling" but I appreciate your explanations and suggestions.
Mar 24
parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Saturday, 25 March 2017 at 02:21:33 UTC, data pulverizer wrote:
 Thanks a lot ... I was half joking playing with the name 
 "mangling" but I appreciate your explanations and suggestions.
This is the internet, I can't tell if you're a newb or sarcastic, and given this is a learn forum I'm going to make a conservative estimate of the former ;) (possibly 'cause I was half asleep when answering) I would however be interested to know if the extern(C++)/__attribute__((overloadable))/Instansiate combo actually worked.
Mar 24
parent data pulverizer <data.pulverizer gmail.com> writes:
On Saturday, 25 March 2017 at 06:17:15 UTC, Nicholas Wilson wrote:
 On Saturday, 25 March 2017 at 02:21:33 UTC, data pulverizer 
 wrote:
 Thanks a lot ... I was half joking playing with the name 
 "mangling" but I appreciate your explanations and suggestions.
This is the internet, I can't tell if you're a newb or sarcastic, and given this is a learn forum I'm going to make a conservative estimate of the former ;) (possibly 'cause I was half asleep when answering) I would however be interested to know if the extern(C++)/__attribute__((overloadable))/Instansiate combo actually worked.
I usually try to be as clear as possible, I just couldn't help slipping in a joke with a name like "mangling" I could not resits. I am definitely a noob to compilers, my day job is a data scientist/statistician, however I really like the D programming language and I am increasing my knowledge by blogging, writing D interfaces for C libraries and I am building a low performance BLAS alternative to GLAS (https://github.com/dataPulverizer/dblas) - its funny because its true! The article I am working on is connecting D to other languages. The draft for my article interfacing D to C and Fortran is here (https://github.com/dataPulverizer/interface-d-c-fortran). I can't decide if name mangling deserves its own topic. Feel free to put in a suggestion/pull request to either.
Mar 25