Thread overview
Using templates to declare function prototypes
Jul 31, 2011
Heinz
Jul 31, 2011
Daniel Murphy
Jul 31, 2011
Heinz
Jul 31, 2011
Daniel Murphy
Jul 31, 2011
Andrej Mitrovic
Jul 31, 2011
Trass3r
Jul 31, 2011
Andrej Mitrovic
July 31, 2011
Hello D community!!!

I'm porting the NVIDIA CUDA headers to D. The CUDA platform runs on multiple
OS, so functions prototypes (in the D way) are declared as "extern(Windows)
..." for MS Windows and "extern(C) ..." for other OS'es.

The thing is that there's no "alias extern(X) myextern;" in D to be used like
this:

version(Windows)
    alias extern(Windows) myextern;
else
    alias extern(C) myextern;

...
myextern void cudaFunct1();
myextern uint cudaFunct2(byte*);

...The C way to accomplish this is:

#ifdef _WIN32
#define CUDAAPI __stdcall
#else
#define CUDAAPI
#endif
...
CUresult CUDAAPI cuInit(unsigned int Flags);

It is a bit redundant and dirty to declare all the functions twice. So i made a template to declare functions prototypes with the corresponding naming convention, here's what i got:

template CUDAAPI(R, P ...)
{
	version(Windows)
		alias extern(Windows) R function(P) CUDAAPI;
	else
		alias extern(C) R function(P) CUDAAPI;
}
...
CUDAAPI!(CUresult, uint) cuInit;

This code actually compiles since its syntax is correct but when linking i
relize that the linker is still looking for the "extern(D)" symbol and by any
means, no matter where i place the extern(X), the compiler is generating the D
mangled symbol (_D5cudad4cuda6cuInitPWkZE5cudad4cuda8CUresult, at least the
template is inserted in the context).
I've tried with DMD 1.030 and the latest 1.069, both with the same result.

I also did a mixin flavored template that also compiles but is even worse because the linker is still stuck with a templated/D mangled symbol, take a look:

template CUDAAPI(string N, R, P ...)
{
	version(Windows)
		mixin("extern(Windows) R " ~ N ~ "(P);");
}
...
mixin CUDAAPI!("cuInit", CUresult, uint);

The generated symbol for this code is: __D5cudad4cuda55__T7CUDAAPIVG6aa6_6375496e6974TE5cud ad4cuda8CUresultTkZ6cuInitWkZE5cudad4cuda8CUresult@4. As you can see, the symbol is still recognized as a template so i discard this code.

I found templates to be a very interesting case of study, templates give languages the fun or the exciting part of programming by presenting challenges in code complexity but still i can not get some parts of my code to work.

Any aproach or ideas on how to accomplish this template or multi extern declaration?

Thank you so much for reading.
July 31, 2011
Use extern(System)?

"Heinz" <malagana15@yahoo.com> wrote in message news:j12hkk$2mcd$1@digitalmars.com...
> Hello D community!!!
>
> I'm porting the NVIDIA CUDA headers to D. The CUDA platform runs on
> multiple
> OS, so functions prototypes (in the D way) are declared as
> "extern(Windows)
> ..." for MS Windows and "extern(C) ..." for other OS'es.
>
> The thing is that there's no "alias extern(X) myextern;" in D to be used
> like
> this:
>
> version(Windows)
>    alias extern(Windows) myextern;
> else
>    alias extern(C) myextern;
>
> ...
> myextern void cudaFunct1();
> myextern uint cudaFunct2(byte*);
>
> ...The C way to accomplish this is:
>
> #ifdef _WIN32
> #define CUDAAPI __stdcall
> #else
> #define CUDAAPI
> #endif
> ...
> CUresult CUDAAPI cuInit(unsigned int Flags);
>
> It is a bit redundant and dirty to declare all the functions twice. So i
> made
> a template to declare functions prototypes with the corresponding naming
> convention, here's what i got:
>
> template CUDAAPI(R, P ...)
> {
> version(Windows)
> alias extern(Windows) R function(P) CUDAAPI;
> else
> alias extern(C) R function(P) CUDAAPI;
> }
> ...
> CUDAAPI!(CUresult, uint) cuInit;
>
> This code actually compiles since its syntax is correct but when linking i
> relize that the linker is still looking for the "extern(D)" symbol and by
> any
> means, no matter where i place the extern(X), the compiler is generating
> the D
> mangled symbol (_D5cudad4cuda6cuInitPWkZE5cudad4cuda8CUresult, at least
> the
> template is inserted in the context).
> I've tried with DMD 1.030 and the latest 1.069, both with the same result.
>
> I also did a mixin flavored template that also compiles but is even worse because the linker is still stuck with a templated/D mangled symbol, take a look:
>
> template CUDAAPI(string N, R, P ...)
> {
> version(Windows)
> mixin("extern(Windows) R " ~ N ~ "(P);");
> }
> ...
> mixin CUDAAPI!("cuInit", CUresult, uint);
>
> The generated symbol for this code is: __D5cudad4cuda55__T7CUDAAPIVG6aa6_6375496e6974TE5cud ad4cuda8CUresultTkZ6cuInitWkZE5cudad4cuda8CUresult@4. As you can see, the symbol is still recognized as a template so i discard this code.
>
> I found templates to be a very interesting case of study, templates give
> languages the fun or the exciting part of programming by presenting
> challenges
> in code complexity but still i can not get some parts of my code to work.
>
> Any aproach or ideas on how to accomplish this template or multi extern declaration?
>
> Thank you so much for reading.


July 31, 2011
Thanks, extern(System) seems to do the job under windows at least, i hope it switch to extern(C) for other systems, can't test it right now. The System version works even with the old DMD 1.030. If this defined version is that old then why it is not documented yet with newer releases?

Thank you for this solution.
July 31, 2011
It is documented! http://www.digitalmars.com/d/1.0/attribute.html#linkage http://www.digitalmars.com/d/2.0/attribute.html#linkage

"Heinz" <malagana15@yahoo.com> wrote in message news:j12itk$2o99$1@digitalmars.com...
> Thanks, extern(System) seems to do the job under windows at least, i hope
> it
> switch to extern(C) for other systems, can't test it right now. The System
> version
> works even with the old DMD 1.030. If this defined version is that old
> then why it
> is not documented yet with newer releases?
>
> Thank you for this solution.


July 31, 2011
Why is there both a System and Windows linkage type if they're the same? Is this a C++ legacy?
July 31, 2011
Am 31.07.2011, 17:34 Uhr, schrieb Andrej Mitrovic <andrej.mitrovich@gmail.com>:

> Why is there both a System and Windows linkage type if they're the
> same? Is this a C++ legacy?

Well Windows always means stdcall while System changes its meaning on Posix.
July 31, 2011
Oh damn I didn't finish reading the sentence:

"System is the same as Windows on Windows platforms, and C on other platforms."

Heh. :)