Interfacing with C

40.1 Calling C Functions

core.stdc.* already declares the C standard library (core.stdc.stdio, stdlib, string, math, ...).

extern(C) int printf(const char* fmt, ...);
extern(C) size_t strlen(const char* s);
extern(C) double sqrt(double x);

import std.string : toStringz, fromStringz;
void main()
{
    printf("Hello from C: %d\n", 42);
    string s = "hello";
    writeln(strlen(s.toStringz));          // D string → null-terminated C string
    char* c = getenv("HOME");
    string home = c.fromStringz.idup;      // C string → D string
}

40.2 C Types, Structs and Callbacks

int, unsigned c_long (core.stdc.config) char* / const(char)* extern(C) struct S (same layout) extern(C) int function(int)

extern(C) struct Point { int x, y; }
extern(C) alias Cmp = int function(const void*, const void*);
extern(C) void qsort(void* base, size_t n, size_t size, Cmp cmp);

extern(C) int compareInts(const void* a, const void* b) nothrow @nogc
{
    return *cast(int*) a - *cast(int*) b;
}
int[] arr = [5, 2, 9];
qsort(arr.ptr, arr.length, int.sizeof, &compareInts);

40.3 ImportC: Compile C Code Directly

ImportC supports C11 plus common extensions. It uses the system C preprocessor for #include. __import inside C files imports D modules.

// mylib.c is compiled by the D compiler itself
// app.d
import mylib;                 // import a .c file like a D module
void main() { mylib_function(); }
dmd app.d mylib.c              # the D compiler compiles C11 code (with its own C parser)

40.4 Binding Generators and Linking

dpp (#include C headers directly in .dpp files), dstep (header → D bindings), bindbc-* packages (static/dynamic bindings for SDL, OpenGL, FreeType, Lua, etc.), derelict (legacy).

Linking: dmd app.d -L-lsqlite3, pragma(lib, "sqlite3");, or libs in dub.json.

40.5 Exposing D to C

extern(C) int d_add(int a, int b) { return a + b; }   // callable from C
// If the D runtime is needed (GC, etc.), call rt_init()/rt_term() from C, or use core.runtime.Runtime
dmd -shared -of=libdlib.so dlib.d          # shared library
dmd -lib -of=libdlib.a dlib.d              # static library
dmd -HC dlib.d                             # generate a C/C++ header (-HCf=dlib.h)