2012-03-18 35 views
6

D'deki dinamik paylaşılan kitaplıklar ile hızlı başlangıç ​​yapmaya çalışıyorum ancak sorun yaşıyorum.d2: C tarafındaki D paylaşılan kitaplıklarda writefln çağrılıyor

Ben dmd -shared ./testlib.d ile aşağıdaki kodu inşa ediyorum:

module testlib; 

import std.c.stdio; 

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

    return (a + 1); 
} 

Bu ince oluşturur ve çalışır. Aşağıdaki fazla D'imsi kaynağının kullanımını yapmaya çalışıyorum Ama ne zaman:

module testlib; 

import std.stdio; 

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

    return (a + 1); 
} 

Bu parçalama arızası vererek başarısız Ben hello ulaşmaya çalışıyorum bir kere. Neyi yanlış yapıyorum?

Python kullanarak hello aramıştım:

import ctypes 

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

print (testlib.hello(10)) 

UPD1: Ben de std.conv.to!(string) gibi Phobos işlevlerini kullanamazsınız görünüyor.

UPD2: Windows'ta böyle bir sorun yok, her şey iyi çalışıyor gibi görünüyor. Mac OS X bundan muzdarip.

UPD3: Muhtemelen, bu GC ile bağlanır. Bir şekilde GC'yi başlatmalıyım, fakat core.memory.GC.enable() hala bölümleme hatasıyla başarısız oluyor.

cevap

5

Çözüm basit ama parlak:

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

Muhtemelen, automagicallylar bu işlevleri çağırmak için Linux ve Mac OS X yolları vardır, ama bu bile memnun değilim.

+1

Belki bunun yerine RAII kullanın? Yani, yeni sınıf 'DRuntime' oluşturun ve 'init 'işlevinizi kurucuya,' bitti '- destructor'a ekleyin. Yani, müşteri sadece bu sınıfın nesnesini yaratır - ve bizim için tüm işi yapar. – Raxillan

+0

Ancak, istemci D yazılmamışsa ne yapmalıyım? Örneğin. C çekirdeği DRuntime'ı nasıl atayabilir? – toriningen

+0

Açıkça C'ye ihtiyacınız varsa, C++ 'class',' new', constructors/destructors desteklemezse, 'init/done' işlevlerinizi her zamanki C-stilinde kullanın. Ve henüz değil, http://dlang.org/cpp_interface.html bakabilirsiniz. – Raxillan