2012-03-18 8 views
6

Estoy tratando de iniciar rápidamente con bibliotecas compartidas dinámicas en D, pero tengo un problema.d2: Llamando a writefln en D bibliotecas compartidas desde el lado C

estoy construyendo siguiente código 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); 
} 

Se construye muy bien, y trabaja. Pero cuando estoy tratando de hacer uso de la siguiente fuente más ish D':

module testlib; 

import std.stdio; 

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

    return (a + 1); 
} 

Se falla con un error de segmentación una vez que estoy tratando de llamar hello. ¿Qué estoy haciendo mal?

estoy llamando hello usando Python:

import ctypes 

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

print (testlib.hello(10)) 

UPD1: Parece que tampoco puedo utilizar funciones como Phobos std.conv.to!(string).

UPD2: No hay tal problema en Windows, todo parece funcionar bien. Mac OS X sufre de esto.

UPD3: Posiblemente, esto está conectado con GC. De alguna manera debo inicializar GC, pero core.memory.GC.enable() aún falla con falla de segmentación.

Respuesta

5

solución es simple, pero brillante:

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(); 
} 

Posiblemente, hay maneras en Linux y Mac OS X para llamar a estas funciones automágicamente, pero estoy satisfecho con incluso esto.

+1

Tal vez, use RAII en su lugar? entonces, cree una nueva clase 'DRuntime' y agregue su función' init' al constructor, 'done' - al destructor. Entonces, el cliente simplemente crea un objeto de esta clase, y hace todo el trabajo para nosotros. – Raxillan

+0

¿Pero qué debo hacer si el cliente no está escrito en D? P.ej. ¿Cómo puede C core instanciar DRuntime descendiente? – toriningen

+0

Si necesita explícitamente C, lo que no tienen soporte C++ 'clase',' nuevo', constructores/destructores, simplemente use sus funciones 'init/done' en el estilo C habitual. Y puede ver http://dlang.org/cpp_interface.html, si aún no. – Raxillan

Cuestiones relacionadas