Thread overview
extern(C) vs. extern(Windows)
Apr 01, 2007
Frits van Bommel
Apr 02, 2007
Mike Parker
Apr 02, 2007
Mike Parker
Apr 02, 2007
Frits van Bommel
Apr 02, 2007
Max Samukha
Apr 02, 2007
Sean Kelly
April 01, 2007
I have many functions. On linux they shall be extern(C), on win32 they
shall be extern(Windows). How do I do that?
April 01, 2007
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.
April 02, 2007
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.
April 02, 2007
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.
April 02, 2007
Mike Parker wrote:
> Frits van Bommel wrote:
[snip]
>> ---
>> version(Windows) {
>>     extern(Windows):
>> } else {
>>     extern(C):
>> }
>> ---
[snip]
> 
> 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
April 02, 2007
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.
April 02, 2007
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?
>>> 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.

Right.  It used to for some odd cases, but this has been fixed.


Sean