D FFI

This is a "remake" of my "Oberon FFI" post. However, now I'm using D in a slightly different manner.

Oberon FFI

D Programming Language

Build System Changes

D compilers generate machine code instead of transpiling to C, so instead of just including generated C code I have to compile and link a new object file. Compilation is taken care of by the following Makefile fragment:

DC := ldc2
DFLAGS := --O3 --release
%.o: %.d dprog.d
	$(DC) $(DFLAGS) -c -<

The important part is the "-c" command-line option. This generates an ELF object file for later linking. Linking is something like the following:

SRC_D := dextension.d dprog.d
OBJ_D := $(SRC_D:.d=.o)
prog: ... $(OBJ_D)
	...

Code Changes

Migration is best done one function at a time, running a test suite in between. For the first step, I copy/pasted one function to a file prefixed with *d*. I had to make the following changes:

I also had to add a new file, *prog.d*, which is the D declaration of all dependencies in the remaining C code. This starts out like:

module prog;

// enums, etc. here

extern (C):

// function declarations here

The D syntax for enums and function declarations is similar enough to C that you might be able to copy-and-paste.

Note that I don't need annotations like `@system`, `nothrow` or `@nogc` because they're implied by the use of `core.stdc` functions or the *betterC* option.

Conclusion

It seems like D is a viable migration path for legacy C code. Perhaps also C++, but I haven't tested that. There is a path onwards too:

In contrast, Go is more fashionable (Rust is really for a different domain), but I totally failed to get c2go to work so incremental migration seems difficult.

Back to my gemlog