View mode: basic / threaded / horizontal-split · Log in · Help
April 01, 2007
extern(C) vs. extern(Windows)
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
Re: extern(C) vs. extern(Windows)
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
Re: extern(C) vs. extern(Windows)
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
Re: extern(C) vs. extern(Windows)
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
Re: extern(C) vs. extern(Windows)
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
Re: extern(C) vs. extern(Windows)
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
Re: extern(C) vs. extern(Windows)
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
Top | Discussion index | About this forum | D home