www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - version not working with extern(Windows) on linux

reply hellcatv hotmail.com writes:
I am porting a few C header files to D, and I'm finding it difficult to get the
versioning working.

specifically, I want to be able to use the same .d file for both windows and
linux

extern (C) {
extern (Windows) {
export void test ();
}
}
this works in windows, and in linux--but it relies on the fact that
extern(Windows) does NOT do anything
a more portable way does NOT work
extern(C) {
export version(Windows){extern (Windows)} void test();
}
the above fails to link in windows though both work in linux
this is using gdc in linux and dmc in windows

any suggestions as to how to get the version to work with the extern (Windows)
command...I want to share a header between the two OS's for ease of use
May 04 2004
parent reply "Walter" <newshound digitalmars.com> writes:
Why use extern (Windows) at all in portable code?

<hellcatv hotmail.com> wrote in message
news:c77jqd$29em$1 digitaldaemon.com...
 I am porting a few C header files to D, and I'm finding it difficult to

 versioning working.

 specifically, I want to be able to use the same .d file for both windows

 linux

 extern (C) {
 extern (Windows) {
 export void test ();
 }
 }
 this works in windows, and in linux--but it relies on the fact that
 extern(Windows) does NOT do anything
 a more portable way does NOT work
 extern(C) {
 export version(Windows){extern (Windows)} void test();
 }
 the above fails to link in windows though both work in linux
 this is using gdc in linux and dmc in windows

 any suggestions as to how to get the version to work with the extern

 command...I want to share a header between the two OS's for ease of use

May 04 2004
parent reply Daniel Horn <hellcatv hotmail.com> writes:
I'm trying to link in opengl32.dll and glut32.dll
so I need to create a gl.d (to replace gl.h) and glut.d (to replace 
glut.h), preferably a gl.d that I can share between linux and windows.

Right now it works, but I am using extern(Windows){ at the top

I could fool the linker by making a specially hacked glut32.def and 
opengl32.def file to alias the extern(C) type exports to the ones 
defined in the dll--is this the preferred method? It seems like changing 
the calling convention to keep cross-platform is not necessarily a good idea

ideally we COULD have a single header file that would serve both linux 
.so and windows .dll's much like gl.h does today
i.e. I think version should also be able to #ifdef out extern(Windows)

Walter wrote:
 Why use extern (Windows) at all in portable code?
 
 <hellcatv hotmail.com> wrote in message
 news:c77jqd$29em$1 digitaldaemon.com...
 
I am porting a few C header files to D, and I'm finding it difficult to

get the
versioning working.

specifically, I want to be able to use the same .d file for both windows

and
linux

extern (C) {
extern (Windows) {
export void test ();
}
}
this works in windows, and in linux--but it relies on the fact that
extern(Windows) does NOT do anything
a more portable way does NOT work
extern(C) {
export version(Windows){extern (Windows)} void test();
}
the above fails to link in windows though both work in linux
this is using gdc in linux and dmc in windows

any suggestions as to how to get the version to work with the extern

(Windows)
command...I want to share a header between the two OS's for ease of use


May 04 2004
next sibling parent reply Andy Friesen <andy ikagames.com> writes:
Daniel Horn wrote:
 I'm trying to link in opengl32.dll and glut32.dll
 so I need to create a gl.d (to replace gl.h) and glut.d (to replace 
 glut.h), preferably a gl.d that I can share between linux and windows.
 
 Right now it works, but I am using extern(Windows){ at the top
 
 I could fool the linker by making a specially hacked glut32.def and 
 opengl32.def file to alias the extern(C) type exports to the ones 
 defined in the dll--is this the preferred method? It seems like changing 
 the calling convention to keep cross-platform is not necessarily a good 
 idea
 
 ideally we COULD have a single header file that would serve both linux 
 .so and windows .dll's much like gl.h does today
 i.e. I think version should also be able to #ifdef out extern(Windows)

This should get you where you want to be: version (Win32) { extern (Windows): } else { extern (C): } void glThingie(...); // this will be extern (Windows) on win32, else // extern(C) void glOtherThingie(...); // et cetera -- andy
May 04 2004
parent reply David Tiktin <dtiktin nospam.totally-bogus.com> writes:
On 04 May 2004, Andy Friesen <andy ikagames.com> wrote:

 This should get you where you want to be:
 
 version (Win32) {
      extern (Windows):
 } else {
      extern (C):
 }
 
 void glThingie(...); // this will be extern (Windows) on win32,else 
                       // extern(C)
 void glOtherThingie(...);
 // et cetera

Great! I had the same problem and your solution works. But I'm new to D, and I'm not clear about the syntax with a colon. Does the effect just continue to then end of the source file? Can you give a reference to where this is explained? Dave -- D.a.v.i.d T.i.k.t.i.n t.i.k.t.i.n [at] a.d.v.a.n.c.e.d.r.e.l.a.y [dot] c.o.m
Jul 08 2004
parent Ben Hinkle <bhinkle4 juno.com> writes:
David Tiktin wrote:

 On 04 May 2004, Andy Friesen <andy ikagames.com> wrote:
 
 This should get you where you want to be:
 
 version (Win32) {
      extern (Windows):
 } else {
      extern (C):
 }
 
 void glThingie(...); // this will be extern (Windows) on win32,else
                       // extern(C)
 void glOtherThingie(...);
 // et cetera

Great! I had the same problem and your solution works. But I'm new to D, and I'm not clear about the syntax with a colon. Does the effect just continue to then end of the source file? Can you give a reference to where this is explained? Dave

see http://www.digitalmars.com/d/attribute.html where it says attribute: affects all declarations until the next } declaration; declaration; ... (or I guess until the end of the file)
Jul 08 2004
prev sibling next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Daniel Horn" <hellcatv hotmail.com> wrote in message
news:c78n8f$tgg$1 digitaldaemon.com...
 I'm trying to link in opengl32.dll and glut32.dll
 so I need to create a gl.d (to replace gl.h) and glut.d (to replace
 glut.h), preferably a gl.d that I can share between linux and windows.

 Right now it works, but I am using extern(Windows){ at the top

 I could fool the linker by making a specially hacked glut32.def and
 opengl32.def file to alias the extern(C) type exports to the ones
 defined in the dll--is this the preferred method?

That will not work, because the linker cannot change the calling convention.
 It seems like changing
 the calling convention to keep cross-platform is not necessarily a good

 ideally we COULD have a single header file that would serve both linux
 .so and windows .dll's much like gl.h does today
 i.e. I think version should also be able to #ifdef out extern(Windows)

I think the easiest way to make this work is just cut and paste the declarations: version (Windows) { extern (Windows): declarations... } else { extern (C) declarations... }
May 04 2004
next sibling parent reply Hauke Duden <H.NS.Duden gmx.net> writes:
Walter wrote:
  > I think the easiest way to make this work is just cut and paste the
 declarations:
 
 version (Windows)
 {
     extern (Windows):
         declarations...
 }
 else
 {
     extern (C)
         declarations...
 }
 

I think copying code is the worst thing you could do. This kind of stuff can quickly become a maintenance nightmare. The whole point of conditional compilation is to have the same piece of code work in different environments, so that you will NOT have to manually copy all changes to all targets (and inevitably forget some). Otherwise you could just as well create different source files for each version and only compile the one you want. Just an idea, but does/could alias work for such situations? Like: version(Windows) alias extern(Windows) extern(MyConvention); else alias extern(C) extern(MyConvention); extern(MyConvention): ... However, my guess is that version will need to become more powerful anyway. There is a lot of conditional compilation stuff that just isn't possible in D right now. Especially boolean expressions among version parameters (i.e. version( a || b && !c) are a must have, IMHO. Hauke
May 04 2004
parent "Walter" <newshound digitalmars.com> writes:
"Hauke Duden" <H.NS.Duden gmx.net> wrote in message
news:c795fn$1kp2$1 digitaldaemon.com...
 Walter wrote:
   > I think the easiest way to make this work is just cut and paste the
 declarations:

can quickly become a maintenance nightmare. The whole point of conditional compilation is to have the same piece of code work in different environments, so that you will NOT have to manually copy all changes to all targets (and inevitably forget some).

Significantly mitigating that is the block can be copied en masse, the extern statement does not have to be added line by line as it would in C++.
 Otherwise you could just as well create different source files for each
 version and only compile the one you want.

What I don't really understand is why even use the Windows calling convention for newly written C code. It offers nothing beyond uglification of the C source.
 Just an idea, but does/could alias work for such situations? Like:

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

 extern(MyConvention):
 ...

That syntactically can work, but it's something I'd rather avoid.
 However, my guess is that version will need to become more powerful
 anyway. There is a lot of conditional compilation stuff that just isn't
 possible in D right now. Especially boolean expressions among version
 parameters (i.e. version( a || b && !c) are a must have, IMHO.

I'm familiar with a lot of uses of expressions for conditional compilation, including using it myself, and over the years I began to suspect it was way overused. Instead, an identifier should be created for each 'feature' one wants to use. Then, && is: version (Foo) version (Bar) version=Feature; || is: version (Foo) version=Feature; version (Bar) version=Feature; and ! is: version (Foo) { } else version=Feature;
Jul 08 2004
prev sibling parent Daniel Horn <hellcatv hotmail.com> writes:
pasting the function definitions twice?? that's so much bloat!
that means double the work every time a new EXT extension gets 
added...sure I could write a script--but it's messy and it would be nice 
if a mechanism existed to automate the procedure

or how about defining that extern(Windows) does something "right" in 
linux :-) (it seems to work properly with extern(Windows) for both linux 
and windows..but given that it's not in the spec I hesitate to ship 
something with it)

Walter wrote:
 "Daniel Horn" <hellcatv hotmail.com> wrote in message
 news:c78n8f$tgg$1 digitaldaemon.com...
 
I'm trying to link in opengl32.dll and glut32.dll
so I need to create a gl.d (to replace gl.h) and glut.d (to replace
glut.h), preferably a gl.d that I can share between linux and windows.

Right now it works, but I am using extern(Windows){ at the top

I could fool the linker by making a specially hacked glut32.def and
opengl32.def file to alias the extern(C) type exports to the ones
defined in the dll--is this the preferred method?

That will not work, because the linker cannot change the calling convention.
It seems like changing
the calling convention to keep cross-platform is not necessarily a good

idea
ideally we COULD have a single header file that would serve both linux
.so and windows .dll's much like gl.h does today
i.e. I think version should also be able to #ifdef out extern(Windows)

I think the easiest way to make this work is just cut and paste the declarations: version (Windows) { extern (Windows): declarations... } else { extern (C) declarations... }

May 04 2004
prev sibling parent reply mike parker <mike aldacron.com> writes:
Daniel Horn wrote:

 I'm trying to link in opengl32.dll and glut32.dll
 so I need to create a gl.d (to replace gl.h) and glut.d (to replace 
 glut.h), preferably a gl.d that I can share between linux and windows.
 
 Right now it works, but I am using extern(Windows){ at the top
 
 I could fool the linker by making a specially hacked glut32.def and 
 opengl32.def file to alias the extern(C) type exports to the ones 
 defined in the dll--is this the preferred method? It seems like changing 
 the calling convention to keep cross-platform is not necessarily a good 
 idea
 
 ideally we COULD have a single header file that would serve both linux 
 .so and windows .dll's much like gl.h does today
 i.e. I think version should also be able to #ifdef out extern(Windows)

For what it's worth, I am at this very moment working on some openGL modules which load the library dynamically. There are separate modules for each OGL version (gl11.d, ..., gl15.d), and a primary gl.d which publicly imports the other modules and handles the loading. Where a full implementation of a version is not implemented (via extensions or otherwise), the supported subset is loaded as extensions. I should be finished very soon and will post the modules on the NG when I am.
May 05 2004
parent reply hellcatv hotmail.com writes:
wow that's really cool
I was working on the same thing
I was only going to do version 1.1 and then force the user to dynamically grab
teh extension functions with the glGetProcAddress (i wrote a wrapper around the
lin and win versions)

but having the program dynamically load the proper extensions as needed (and
perhaps throw an exception in the event of a missing extension) would probably
be better...
I can 
To see my work-in-progress check out
http://graphics.stanford.edu/~danielrh/d/

it compiles and runs a glut test app on both win and lin :-)
--Daniel

PS:I haven't tried to call an extension function yet
In article <c79me1$2cvi$1 digitaldaemon.com>, mike parker says...
Daniel Horn wrote:

 I'm trying to link in opengl32.dll and glut32.dll
 so I need to create a gl.d (to replace gl.h) and glut.d (to replace 
 glut.h), preferably a gl.d that I can share between linux and windows.
 
 Right now it works, but I am using extern(Windows){ at the top
 
 I could fool the linker by making a specially hacked glut32.def and 
 opengl32.def file to alias the extern(C) type exports to the ones 
 defined in the dll--is this the preferred method? It seems like changing 
 the calling convention to keep cross-platform is not necessarily a good 
 idea
 
 ideally we COULD have a single header file that would serve both linux 
 .so and windows .dll's much like gl.h does today
 i.e. I think version should also be able to #ifdef out extern(Windows)

For what it's worth, I am at this very moment working on some openGL modules which load the library dynamically. There are separate modules for each OGL version (gl11.d, ..., gl15.d), and a primary gl.d which publicly imports the other modules and handles the loading. Where a full implementation of a version is not implemented (via extensions or otherwise), the supported subset is loaded as extensions. I should be finished very soon and will post the modules on the NG when I am.

May 04 2004
parent J Anderson <REMOVEanderson badmama.com.au> writes:
hellcatv hotmail.com wrote:

wow that's really cool
I was working on the same thing
I was only going to do version 1.1 and then force the user to dynamically grab
teh extension functions with the glGetProcAddress (i wrote a wrapper around the
lin and win versions)

but having the program dynamically load the proper extensions as needed (and
perhaps throw an exception in the event of a missing extension) would probably
be better...
I can 
To see my work-in-progress check out
http://graphics.stanford.edu/~danielrh/d/
  

If your talking about openGL extensions. I ported GLee which supports over 300 opengl extensions. -- -Anderson: http://badmama.com.au/~anderson/
May 04 2004