www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Linking external functions?

reply DLearner <bmqazwsx123 gmail.com> writes:
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?
Apr 18 2023
next sibling parent reply ag0aep6g <anonymous example.com> writes:
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.
Apr 18 2023
parent reply DLearner <bmqazwsx123 gmail.com> writes:
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?
Apr 18 2023
parent ag0aep6g <anonymous example.com> writes:
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.
Apr 18 2023
prev sibling parent reply thinkunix <thinkunix zoho.com> writes:
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
Apr 18 2023
parent reply DLearner <bmqazwsx123 gmail.com> writes:
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.
Apr 18 2023
parent thinkunix <thinkunix zoho.com> writes:
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.
Apr 18 2023