Re: Linking external functions?

2023-04-18 Thread thinkunix via Digitalmars-d-learn

DLearner via Digitalmars-d-learn wrote:

On Tuesday, 18 April 2023 at 21:31:21 UTC, thinkunix wrote:
[...]

If not calling C code, why use extern(C) for D code?
Wanted to test out options of calling D routine (possibly -betterC) from 
both C and (full) D.





OK, thanks.


Re: Linking external functions?

2023-04-18 Thread DLearner via Digitalmars-d-learn

On Tuesday, 18 April 2023 at 21:31:21 UTC, thinkunix wrote:
[...]

If not calling C code, why use extern(C) for D code?
Wanted to test out options of calling D routine (possibly 
-betterC) from both C and (full) D.





Re: Linking external functions?

2023-04-18 Thread thinkunix via Digitalmars-d-learn

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
 R _D9ExtCallee12__ModuleInfoZ
 W _D9ExtCalleeQkFZv

$ nm ExtMain.o | grep ExtCallee
 U _D9ExtCalleeQkFZv


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

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

$ nm ExtMain.o | grep ExtCallee
 U ExtCallee


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


Re: Linking external functions?

2023-04-18 Thread ag0aep6g via Digitalmars-d-learn

On Tuesday, 18 April 2023 at 20:05:05 UTC, DLearner wrote:

Is the declaration inside main not visible to the linker?


It affects the (fully qualified and mangled) name of the 
function. Compare:


```d
extern(C) void ExtCallee();
pragma(msg, ExtCallee.mangleof); /* ExtCallee (correct name) */
void main()
{
extern(C) void ExtCallee();
pragma(msg, ExtCallee.mangleof); /* 
_D7ExtMain4mainFZ9ExtCalleeUZv (incorrect) */

}
```

I don't know the rationale behind that behavior, if there is one. 
Generally, just put your `extern(C)` prototypes in module scope.


Re: Linking external functions?

2023-04-18 Thread DLearner via Digitalmars-d-learn

On Tuesday, 18 April 2023 at 20:00:18 UTC, ag0aep6g wrote:

On Tuesday, 18 April 2023 at 19:49:04 UTC, DLearner wrote:

```
void main() {
   import std.stdio;
   extern(C) void ExtCallee();
```


Move that declaration out of main.


Thanks - worked!

Is the declaration inside main not visible to the linker?


Re: Linking external functions?

2023-04-18 Thread ag0aep6g via Digitalmars-d-learn

On Tuesday, 18 April 2023 at 19:49:04 UTC, DLearner wrote:

```
void main() {
   import std.stdio;
   extern(C) void ExtCallee();
```


Move that declaration out of main.


Linking external functions?

2023-04-18 Thread DLearner via Digitalmars-d-learn

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__);
}
```
Then:
```
dmd ExtCallee -c
```
which worked, producing .obj file.

However:
```
dmd ExtCallee.obj -run ExtMain
lld-link: error: undefined symbol: __D7ExtMain4mainFZ9ExtCalleeUZv

referenced by ExtMain.obj:(__Dmain)

Error: linker exited with status 1
```

Ideas?