【问题标题】:d2: Calling writefln in D shared libraries from C sided2:从C端调用D共享库中的writefln
【发布时间】:2012-03-18 12:24:04
【问题描述】:

我正在尝试使用 D 中的动态共享库快速入门,但遇到了问题。

我正在使用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);
}

它构建良好,并且工作正常。但是当我尝试使用以下更多 D'ish 来源时:

module testlib;

import std.stdio;

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

    return (a + 1);
}

一旦我尝试调用hello,它就会因分段错误而失败。我做错了什么?

我正在使用 Python 调用 hello

import ctypes

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

print (testlib.hello(10))

UPD1:好像我也不能使用像std.conv.to!(string)这样的Phobos功能。

UPD2: 在 Windows 上没有这样的问题,一切似乎都运行良好。 Mac OS X 也受此困扰。

UPD3:这可能与GC有关。我必须以某种方式初始化 GC,但 core.memory.GC.enable() 仍然因分段错误而失败。

【问题讨论】:

    标签: shared-libraries d


    【解决方案1】:

    解决方案简单但绝妙:

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

    可能,Linux 和 Mac OS X 中有一些方法可以自动调用这些函数,但我对此感到满意。

    【讨论】:

    • 也许,改用 RAII?因此,创建新类 DRuntime 并将您的 init 函数添加到构造函数,done - 到析构函数。因此,客户只需创建此类的对象 - 它为我们完成了所有工作。
    • 但是如果client不是用D写的怎么办?例如。 C核心如何实例化DRuntime后代?
    • 如果您需要明确的 C,C++ classnew 不支持构造函数/析构函数 - 只需以通常的 C 风格使用您的 init/done 函数。如果还没有,您可以查看dlang.org/cpp_interface.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多