Linking external functions?

thinkunix thinkunix at zoho.com
Tue Apr 18 21:31:21 UTC 2023


DLearner via Digitalmars-d-learn wrote:
> Wanted to try out linking two source files independantly compiled.
> 
> ExtCallee.d source file:
> ```
> extern(C) void ExtCallee() {
>     import std.stdio;
> 
>     writeln("Entered: ", __FUNCTION__);
>     writeln("Exiting: ", __FUNCTION__);
> }
> ```
> ExtMain.d source file:
> ```
> void main() {
>     import std.stdio;
>     extern(C) void ExtCallee();
> 
> 
>     writeln("Entered: ", __FUNCTION__);
> 
>     ExtCallee();
> 
>     writeln("Exiting: ", __FUNCTION__);
> }


What is the advantage of using extern(C)?
Since both are D source files, why wouldn't you do just this:

```d
// ExtCallee.d
void ExtCallee()
{
         import std.stdio;

         writeln("Entered:  ", __FUNCTION__);
         writeln("Exiting:  ", __FUNCTION__);
}
```

```d
// ExtMain.d
void main()
{
         import std.stdio;
         import ExtCallee;

         writeln("Entered:  ", __FUNCTION__);

	// I had to scope this to get it to compile
         // If instead I put the function in myfn.d and
         // did "import myfn;" it works without the scope operator.
         ExtCallee.ExtCallee();

         writeln("Exiting:  ", __FUNCTION__);
}
```

Compile with:
$ dmd ExtCallee.d ExtMain.d -of=prog


Without extern(C), the linker mangles names:

$ nm ExtCallee.o | grep ExtCallee
0000000000000000 R _D9ExtCallee12__ModuleInfoZ
0000000000000000 W _D9ExtCalleeQkFZv

$ nm ExtMain.o | grep ExtCallee
                  U _D9ExtCalleeQkFZv


With extern(C), the linker does not mangle names:

$ nm ExtCallee.o | grep ExtCallee
0000000000000000 W ExtCallee
0000000000000000 R _D9ExtCallee12__ModuleInfoZ

$ nm ExtMain.o | grep ExtCallee
                  U ExtCallee


If not calling C code, why use extern(C) for D code?
scot


More information about the Digitalmars-d-learn mailing list