2012-03-18 13 views
6

Sto cercando di avviare rapidamente con librerie dinamiche condivise in D, ma sto avendo un problema.d2: chiamata writefln in D librerie condivise dal lato C

Sto costruendo seguente codice con dmd -shared ./testlib.d:

module testlib; 

import std.c.stdio; 

extern (C) export int hello(int a) { 
    printf("Number is %d", a); 

    return (a + 1); 
} 

Costruisce bene, e funziona. Ma quando sto cercando di fare uso di seguire più fonte ish D':

module testlib; 

import std.stdio; 

extern (C) export int hello(int a) { 
    writefln("Number is %d", a); 

    return (a + 1); 
} 

non riesce con errore di segmentazione una volta che sto cercando di chiamare hello. Che cosa sto facendo di sbagliato?

sto chiamando hello utilizzando Python:

import ctypes 

testlib = ctypes.CDLL('testlib.dylib'); 

print (testlib.hello(10)) 

UPD1: Sembra che anche io non riesco a utilizzare le funzioni di Phobos come std.conv.to!(string).

UPD2: Non c'è alcun problema su Windows, tutto sembra funzionare correttamente. Mac OS X ne soffre.

UPD3: Possibilmente, questo è collegato con GC. Devo in qualche modo inizializzare GC, ma core.memory.GC.enable() non riesce ancora con errore di segmentazione.

risposta

5

soluzione è semplice, ma geniale:

static import core.runtime; 

extern (C) export void init() { // to be called once after loading shared lib 
    core.runtime.Runtime.initialize(); 
} 

extern (C) export void done() { // to be called before unloading shared lib 
    core.runtime.Runtime.terminate(); 
} 

Forse, ci sono modi in Linux e Mac OS X per chiamare queste funzioni automagically, ma io sono soddisfatto di anche questo.

+1

Forse, utilizzare RAII invece? quindi, crea una nuova classe 'DRuntime' e aggiungi la funzione' init' al costruttore, 'done' - al distruttore. Quindi, il cliente crea solo l'oggetto di questa classe e fa tutto il lavoro per noi. – Raxillan

+0

Ma cosa dovrei fare se il client non è scritto in D? Per esempio. come può il C core istanziare il discendente DRuntime? – toriningen

+0

Se avete bisogno esplicitamente di C, cosa non ha il 'class',' new', supporto costruttori/distruttori di C++ - usate semplicemente le funzioni 'init/done' nel solito stile C. E puoi guardare http://dlang.org/cpp_interface.html, se non ancora. – Raxillan