www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Conditional compilation

reply "finalpatch" <fengli gmail.com> writes:
Hi folks,

I need to apply different calling conventions to the same 
interfaces when compiling for different platform. It's something 
like this:

OSX:

interface InterfaceA : IUnknown
{
extern(C):
     ...
}

Windows:

interface InterfaceA : IUnknown
{
     ...
}

I have to add extern(C) on OSX because apparently when the 
compiler sees IUnknown it automatically assumes the calling 
convention is extern(Windows) and in order to maintain 
compatibility with existing system I have to explicitly declare 
them as extern(C).

Now I have several dozens of interfaces like the above. I don't 
want to repeat them for OSX and Windows because the interface 
definitions are identical except the extern(C) line.

I have tried using version() like this:

interface InterfaceA : IUnknown {
     version(OSX)
     {
         extern(C):
     }
     ...methohds.
}

but it doesn't work because version limits the scope of the 
extern(C). static if has the same problem.

In C/C++ this is really easy, I can simply define a macro which 
expands to extern(C) on OSX and nothing on windows. Is there any 
way to achieve this in D without repeating the interface 
definitions?
Jun 07 2013
next sibling parent reply "finalpatch" <fengli gmail.com> writes:
string mixins and template mixins don't work either.

On Friday, 7 June 2013 at 12:14:45 UTC, finalpatch wrote:
 Hi folks,

 I need to apply different calling conventions to the same 
 interfaces when compiling for different platform. It's 
 something like this:

 OSX:

 interface InterfaceA : IUnknown
 {
 extern(C):
     ...
 }

 Windows:

 interface InterfaceA : IUnknown
 {
     ...
 }

 I have to add extern(C) on OSX because apparently when the 
 compiler sees IUnknown it automatically assumes the calling 
 convention is extern(Windows) and in order to maintain 
 compatibility with existing system I have to explicitly declare 
 them as extern(C).

 Now I have several dozens of interfaces like the above. I don't 
 want to repeat them for OSX and Windows because the interface 
 definitions are identical except the extern(C) line.

 I have tried using version() like this:

 interface InterfaceA : IUnknown {
     version(OSX)
     {
         extern(C):
     }
     ...methohds.
 }

 but it doesn't work because version limits the scope of the 
 extern(C). static if has the same problem.

 In C/C++ this is really easy, I can simply define a macro which 
 expands to extern(C) on OSX and nothing on windows. Is there 
 any way to achieve this in D without repeating the interface 
 definitions?
Jun 07 2013
parent "Anthony Goins" <neontotem gmail.com> writes:
On Friday, 7 June 2013 at 12:20:23 UTC, finalpatch wrote:
 string mixins and template mixins don't work either.

 On Friday, 7 June 2013 at 12:14:45 UTC, finalpatch wrote:
 Hi folks,

 I need to apply different calling conventions to the same 
 interfaces when compiling for different platform. It's 
 something like this:

 OSX:

 interface InterfaceA : IUnknown
 {
 extern(C):
    ...
 }

 Windows:

 interface InterfaceA : IUnknown
 {
    ...
 }

 I have to add extern(C) on OSX because apparently when the 
 compiler sees IUnknown it automatically assumes the calling 
 convention is extern(Windows) and in order to maintain 
 compatibility with existing system I have to explicitly 
 declare them as extern(C).

 Now I have several dozens of interfaces like the above. I 
 don't want to repeat them for OSX and Windows because the 
 interface definitions are identical except the extern(C) line.

 I have tried using version() like this:

 interface InterfaceA : IUnknown {
    version(OSX)
    {
        extern(C):
    }
    ...methohds.
 }

 but it doesn't work because version limits the scope of the 
 extern(C). static if has the same problem.

 In C/C++ this is really easy, I can simply define a macro 
 which expands to extern(C) on OSX and nothing on windows. Is 
 there any way to achieve this in D without repeating the 
 interface definitions?
string mixin will work import std.stdio; enum :string { //define relevant functions in this string x1 = `void testfunc(string str) { writeln(str); }` } version(X) { extern(C) mixin(x1); string str2 = "c version"; } version(Y) { extern(Windows) mixin(x1); string str2 = "windows version"; } void main() { testfunc(str2); } Yes it's ... well ... not very ... umm But it works :) extern(system) MIGHT be a better option.
Jun 07 2013
prev sibling next sibling parent "Mike Parker" <aldacron gmail.com> writes:
On Friday, 7 June 2013 at 12:14:45 UTC, finalpatch wrote:
 Hi folks,

 I need to apply different calling conventions to the same 
 interfaces when compiling for different platform.
extern(System) On Windows, it will be seen by the compiler as extern(Windows), elsewhere as extern(C).
Jun 07 2013
prev sibling parent "Chris Nicholson-Sauls" <ibisbasenji gmail.com> writes:
There is the aforementioned extern(system), which is probably 
your best bet.  But I'm wondering if your design could seperate 
the connection to IUnknown for non-Windows builds?  Something 
like this:

version(Windows) interface _Inter_ : IUnknown {}
else interface _Inter_ {}

// later

interface InterfaceA : _Inter_ {
     //...
}
Jun 08 2013