www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - extern(C) vs. extern(Windows)

reply "Frank Benoit (keinfarbton)" <benoit tionex.removethispart.de> writes:
I have many functions. On linux they shall be extern(C), on win32 they
shall be extern(Windows). How do I do that?
Apr 01 2007
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Frank Benoit (keinfarbton) wrote:
 I have many functions. On linux they shall be extern(C), on win32 they
 shall be extern(Windows). How do I do that?

Put this right above them: --- version(Windows) { extern(Windows): } else { extern(C): } --- (assuming extern(C) for anything but Windows) If any other functions follow them, add "extern(D):" afterwards to restore the default calling convention and mangling.
Apr 01 2007
parent reply Mike Parker <aldacron71 yahoo.com> writes:
Frits van Bommel wrote:
 Frank Benoit (keinfarbton) wrote:
 I have many functions. On linux they shall be extern(C), on win32 they
 shall be extern(Windows). How do I do that?

Put this right above them: --- version(Windows) { extern(Windows): } else { extern(C): } --- (assuming extern(C) for anything but Windows) If any other functions follow them, add "extern(D):" afterwards to restore the default calling convention and mangling.

As I understand it, you have to do this without the brackets: ===================== version(Windows) extern(Windows): else extern(C): ===================== This is how I do it in Derelict and it works fine. The reason I do this is because of the following section from the Attributes documentation: ===================== attribute: affects all declarations until the next } declaration; declaration; ... ===================== So according to this, wrapping the externs within bracketed version statements should have no effect on declarations following the closing bracket. I haven't tried it with brackets, but if it works then either the implementation or the documentation is wrong.
Apr 02 2007
next sibling parent Mike Parker <aldacron71 yahoo.com> writes:
Mike Parker wrote:
 Frits van Bommel wrote:

 (assuming extern(C) for anything but Windows)


I should also add that extern(Windows) should only be used for interfacing with functions that are declared as __stdcall on the C side (which is how PASCAL, WINAPI, APIPRIVATE, CALLBACK, and APIENTRY are all defined). Anything not explicitly declared __stdcall, or anything explicitly declared __cdecl, should be extern(C) instead.
Apr 02 2007
prev sibling next sibling parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Mike Parker wrote:
 Frits van Bommel wrote:

 ---
 version(Windows) {
     extern(Windows):
 } else {
     extern(C):
 }
 ---


 
 As I understand it, you have to do this without the brackets:
 
 =====================
 version(Windows)
     extern(Windows):
 else
     extern(C):
 =====================

The braces are redundant if there's only one thing in them, yes. But adding them doesn't change the effect (in other words: you don't _have_ to do it without them, but you _can_) and I typically just put them in even where they aren't strictly needed. (IMO that makes it clearer what exactly is compiled)
 This is how I do it in Derelict and it works fine. The reason I do this 
 is because of the following section from the Attributes documentation:
 
 =====================
 attribute:        affects all declarations until the next }
     declaration;
     declaration;
     ...
 =====================
 
 So according to this, wrapping the externs within bracketed version 
 statements should have no effect on declarations following the closing 
 bracket. I haven't tried it with brackets, but if it works then either 
 the implementation or the documentation is wrong.

The braces don't have anything to do with attributes, so you're looking in the wrong place. You should have been looking at http://www.digitalmars.com/d/version.html, especially the line "No new scope is introduced, even if the DeclarationBlock or Statement is enclosed by { }." That line should probably be something like "affects all declarations until the end of the current scope". I've created a bug report: http://d.puremagic.com/issues/show_bug.cgi?id=1090
Apr 02 2007
prev sibling parent reply Max Samukha <samukha voliacable.com> writes:
On Mon, 02 Apr 2007 19:23:08 +0900, Mike Parker <aldacron71 yahoo.com>
wrote:

Frits van Bommel wrote:
 Frank Benoit (keinfarbton) wrote:
 I have many functions. On linux they shall be extern(C), on win32 they
 shall be extern(Windows). How do I do that?

Put this right above them: --- version(Windows) { extern(Windows): } else { extern(C): } --- (assuming extern(C) for anything but Windows) If any other functions follow them, add "extern(D):" afterwards to restore the default calling convention and mangling.

As I understand it, you have to do this without the brackets: ===================== version(Windows) extern(Windows): else extern(C): =====================

You can use brackets because version does not create a scope.
This is how I do it in Derelict and it works fine. The reason I do this 
is because of the following section from the Attributes documentation:

=====================
attribute:		affects all declarations until the next }
     declaration;
     declaration;
     ...
=====================

So according to this, wrapping the externs within bracketed version 
statements should have no effect on declarations following the closing 
bracket. I haven't tried it with brackets, but if it works then either 
the implementation or the documentation is wrong.

Apr 02 2007
parent Sean Kelly <sean f4.ca> writes:
Max Samukha wrote:
 On Mon, 02 Apr 2007 19:23:08 +0900, Mike Parker <aldacron71 yahoo.com>
 wrote:
 
 Frits van Bommel wrote:
 Frank Benoit (keinfarbton) wrote:
 I have many functions. On linux they shall be extern(C), on win32 they
 shall be extern(Windows). How do I do that?

--- version(Windows) { extern(Windows): } else { extern(C): } --- (assuming extern(C) for anything but Windows) If any other functions follow them, add "extern(D):" afterwards to restore the default calling convention and mangling.

===================== version(Windows) extern(Windows): else extern(C): =====================

You can use brackets because version does not create a scope.

Right. It used to for some odd cases, but this has been fixed. Sean
Apr 02 2007