How do I make an extern function?

Steven Schveighoffer schveiguy at yahoo.com
Tue Jun 29 04:43:46 PDT 2010


On Tue, 29 Jun 2010 06:24:42 -0400, Simen kjaeraas  
<simen.kjaras at gmail.com> wrote:

> BCS <none at anon.com> wrote:
>
>> The issue is that the function called from module a is
>> _D1a3fooFZv where the function defined in module b is
>> _D1b3fooFZv ('a' <-> 'b') so they aren't the same function. extern(C)  
>> works because C doesn't mangle names so the function is foo in both  
>> cases.
>
> I know. I just react to 'extern void foo();' being treated as a
> function that must be in a. I would expect extern to indicate it lies
> elsewhere in the program.

D symbol names are mangled with their modules, so it is impossible for the  
compiler to know what module it will be in.  The fact that it assumes the  
current module is probably very counterintuitive.   Use extern(C) if you  
do not want mangled names.

>
>
>> You can resolve this by having a a.di file with the extern foo(); in it  
>> (DMD has a flag to generate such a file for you). OTOH without knowing  
>> what you are doing, I can't tell if this is the correct solution.
>
> I'm trying to create a framework in which the user may provide his own
> foo( ), so the name of module b is impossible to know.

Then the symbol is impossible to know.  D symbols *must* mangle with their  
module names.  Use extern(C) to avoid this.  extern(C) functions work just  
as good as D functions, and for all intents and purposes, are equivalent.   
Just their names are not mangled, so you cannot have overloads.

> torhu <no at spam.invalid> wrote:
>>   You could always create a b.di file, if that doesn't defeat the  
>> purpose.
>
> Jonathan M Davis <jmdavisprog at gmail.com> wrote:
>> Um, extern isn't needed in D. All you need to do is make the function  
>> public and then import the module.
>
> If only life were easy, eh? Module b is user-supplied, so I can't import
> it.
>

Have you thought of using interfaces?  This is exactly why interfaces  
exist (to call functions without knowing who implemented them).

What I would do is something like this:

interface Foo
{
    void foo1(int x);
    int foo1(string y);
}

extern extern(C) Foo getImplementation();

getImplementation().foo1(1);
getImplementation().foo1("hi");


Then your client lib has to define their implementation of Foo, and must  
define one extern (C) function called getImplementation.

Or you could make getImplementation a @property:

extern extern(C) @property Foo implementation();

implementation.foo1(1);
implementation.foo1("hi");

-Steve


More information about the Digitalmars-d-learn mailing list