Thread overview
D: How would one make a shared dynamically linked D library?
Nov 08
BoQsc
Nov 08
Hipreme
Nov 09
IchorDev
November 08

I would like to export some functionality as external shared dynamically linked D library.

Is it possible to do that in D Language and what are limitations?

A simple writeln example would be great.

What I expect is an executable that uses functions, variables, classes, modules from compiled external shared D dynamic library.

Example of shared dynamic libraries depending on other shared dynamic libraries would be great as well.

November 09
Currently stick to ldc.

Dub's defaults will "just work" except:

- On *nix where you have to either set/patch the ``RPATH`` or set ``LD_LIBRARY_PATH``.
- For executables on Windows in which you need to set the dflag ``-dllimport=all``.


From a README of mine (for Posix):


To get the loading of sidero shared libraries you will need to set the LD path before execution.

E.g. export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/projects/ProjectSidero/eventloop/examples/networking

or you can patch the binary:

patchelf --force-rpath --set-rpath ~/projects/ProjectSidero/eventloop/examples/networking ./example_networking
November 08

On Wednesday, 8 November 2023 at 11:48:58 UTC, BoQsc wrote:

>

I would like to export some functionality as external shared dynamically linked D library.

Is it possible to do that in D Language and what are limitations?

A simple writeln example would be great.

What I expect is an executable that uses functions, variables, classes, modules from compiled external shared D dynamic library.

Example of shared dynamic libraries depending on other shared dynamic libraries would be great as well.

For a complete reference, check: https://wiki.dlang.org/Win32_DLLs_in_D

Create a dub project.
Set its targetType to dynamicLibrary.

Now, create a function:

module dllmodule;

version(Windows)
{
    import core.sys.windows.dll;
    mixin SimpleDllMain;
}

export extern(C) void helloWorld()
{
    import std.stdio;
    writeln("DLL: Hello World");
}

Now, when you enter dub, you'll get a .dll on windows, and a .so on linux.
You can use any compiler of your preference.

Now, whenever you need to load this dll, you'll need to call:

module my_app;

extern(C) void function helloWorld();

void main()
{
    import core.runtime;
    void* dllmodule = Runtime.loadLibrary("dllmodule.dll");
    version(Windows)
    {
        import core.sys.windows.dll;
        helloWorld =  cast(typeof(helloWorld))GetProcAddress(dllmodule, "helloWorld");
    }
    else version(Posix)
    {
        import core.sys.posix.dlfcn;
        helloWorld = cast(typeof(helloWorld))dlsym(dllmodule, "helloWorld");
    }
    helloWorld();
}

With that, there it is.
You also may need to call core.runtime.rt_init() if you're not calling from D

November 09

On Wednesday, 8 November 2023 at 11:48:58 UTC, BoQsc wrote:

>

I would like to export some functionality as external shared dynamically linked D library.

Is it possible to do that in D Language

Yes, as long as the symbols you want to use externally are public, which is the default.
When it comes to linking, the main factor is usually matching symbol mangling. In C you would help users do this by distributing your header files. In D it's more common to distribute your source code, so if you want to distribute a "header" you'll need to remove your function bodies:

//regular function:
int add(int x, int y) nothrow{
  x += y;
  return x;
}

//for a D "header":
int add(int x) nothrow;
>

what are limitations?

The desired template instantiations must be generated at compile time, not at link time. CTFE probably won't work.

>

Example of shared dynamic libraries depending on other shared dynamic libraries would be great as well.

There should be no material difference to using a shared library from an executable binary.