Thread overview
Making a D library for a C executable
Apr 27, 2023
Jan Allersma
Apr 27, 2023
Mike Parker
Apr 27, 2023
Jan Allersma
Apr 28, 2023
Jan Allersma
Apr 28, 2023
Jan Allersma
April 27, 2023

Hello,

I see some examples on the internet on how to call C(++) in D. But I want to do it the other way around. Because of (probably) linkage issues, this way seems easier. I have this D code:

import std.stdio;

int maint() {
  writeln("Returning some random stuff...");
  return 10;
}

extern (C++) int foo() {
  return maint();
}

And this CPP source file:

#include <iostream>

int main() {
  std::cout << "deede" << foo() << std::endl;
}

This is some gibberish, but the point is that foo needs to be called from the D source file.

In Bash I compile it and get a response:

$ g++ ../build/libshared-api.so main.cpp
main.cpp: In function ‘int main()’:
main.cpp:4:27: error: ‘foo’ was not declared in this scope
    4 |   std::cout << "deede" << foo() << std::endl;
      |

Apparently foo isn't found from the CPP source file. Anyone some ideas on how to solve this? :)

April 27, 2023

On Thursday, 27 April 2023 at 20:32:24 UTC, Jan Allersma wrote:

>
Apparently foo isn't found from the CPP source file. Anyone some ideas on how to solve this? :)

That's a compilation error, not a linker problem. You need to tell the compiler about the function with a prototype:

#include <iostream>

int foo();

int main() {
  std::cout << "deede" << foo() << std::endl;
}
April 27, 2023

On Thursday, 27 April 2023 at 21:05:00 UTC, Mike Parker wrote:

>

That's a compilation error, not a linker problem. You need to tell the compiler about the function with a prototype:

Declaring the function does fix the compiler problem. However, I do get a linker error once I compile that:

$ g++ ../build/libshared-api.so main.cpp
/usr/bin/ld: /tmp/ccNMKxEE.o: in function `main':
main.cpp:(.text+0x2a): undefined reference to `foo()'
collect2: error: ld returned 1 exit status
April 27, 2023

On 4/27/23 5:29 PM, Jan Allersma wrote:

>

On Thursday, 27 April 2023 at 21:05:00 UTC, Mike Parker wrote:

>

That's a compilation error, not a linker problem. You need to tell the compiler about the function with a prototype:

Declaring the function does fix the compiler problem. However, I do get a linker error once I compile that:

$ g++ ../build/libshared-api.so main.cpp
/usr/bin/ld: /tmp/ccNMKxEE.o: in function `main':
main.cpp:(.text+0x2a): undefined reference to `foo()'
collect2: error: ld returned 1 exit status

You may have to link the library second. Sometimes linkers are particular about object order.

Also, please include your commands for building the D library so reproduction is possible.

-Steve

April 28, 2023

On Thursday, 27 April 2023 at 21:34:17 UTC, Steven Schveighoffer wrote:

>

You may have to link the library second. Sometimes linkers are particular about object order.

Hi Steve,

Your suggestion worked! Reversing the order solved the problem. I have another problem that I'm facing, but that is something hardly related to this so I'll open a new thread. Thanks :)

April 28, 2023

On Thursday, 27 April 2023 at 21:34:17 UTC, Steven Schveighoffer wrote:

>

Also, please include your commands for building the D library so reproduction is possible.

-Steve

I used to dub run to solve the problem, nothing special. My dub.json isn't that interesting either, but I'll show it anyway for the sake of reproduction purposes:

{
        "authors": [
                "Jan Allersma"
        ],
        "copyright": "Copyright © 2023, Jan Allersma",
        "dependencies": {
                "d2sqlite3": "~>1.0.0",
                "secured": "~>2.0.2"
        },
        "description": "A minimal D application.",
        "license": "proprietary",
        "name": "shared-api",
        "targetType": "dynamicLibrary",
        "targetPath": "../build"
}

For people that use a Linux machine and don't have experience with using shared libraries just like me: Don't forget to add your shared library to a library path (e.g. /usr/local/lib). And just to be sure, I also executed ldconfig in Bash.