如何在C程序中链接D库?

时间:2016-02-04 16:37:54

标签: c linux linker shared-libraries d

我想调用使用C程序中标准D库的D函数,我该如何在linux中完成?

静态链接它似乎不起作用(我得到了可怕的“未定义的引用`_Dmodule_ref'”以及460个其他错误,即使还链接了D主函数),所以我试图按照说明进行操作https://dlang.org/dll-linux.html。感谢Ian Abbott对指示的帮助。我已将它们提炼为以下工作最小的hello world示例:

mkdir -p /tmp/dlib
cd /tmp/dlib
cat ->hello_d.d <<EOF
import core.stdc.stdio;
extern(C) void hello_d() {
    printf( "hello from d\n");
}
EOF

cat ->main.c <<EOF
#include <stdlib.h>
#include <dlfcn.h>

int main() {
    void *lh = dlopen( "/tmp/dlib/libhello.so", RTLD_LAZY);
    if( !lh) exit( 1);
    void (*hello_d)() = dlsym( lh, "hello_d");
    if( dlerror()) exit( 2);

    (*hello_d)();

    dlclose(lh);
}
EOF

dmd -c hello_d.d -fPIC
dmd -oflibhello.so hello_d.o -shared -defaultlib=libphobos2.so -L-rpath=/tmp/dlib
gcc -c main.c
gcc -rdynamic main.o -o main -ldl
./main
# Expect "hello from d"
cd -

然而,指令依赖于core.stdc.stdio和c printf函数,但我想使用d库std.stdio和d writeln函数。如果我这样做,运行主程序时会出现Segmentation故障。 请建议我如何将d函数(使用标准d库)链接到c程序中。

1 个答案:

答案 0 :(得分:0)

分段错误和链接错误的原因是缺少必需的库。这可以通过链接它们来修复。此外,d函数必须是“c兼容”的,所以使它“nothrow”是一个好主意。下面是解决原始问题的代码。

    mkdir -p /tmp/dlib
    cd /tmp/dlib
    cat ->hello_d.d <<EOF
    import std.stdio;
    extern(C) void hello_d() nothrow {
        try { writeln( "hello from d"); } catch( Throwable t) {}
    }
    EOF

    cat ->main.c <<EOF
    int main() {
        if( !rt_init()) { return 1; }
        hello_d();
        rt_term();
        return 0;
    }
    EOF

    gcc -c main.c
    dmd -c hello_d.d
    gcc -rdynamic main.o hello_d.o -o main -m64 -L/usr/lib/x86_64-linux-gnu -Xlinker --export-dynamic -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic -lpthread -lm -lrt -ldl 
    ./main
    # Expect "hello from d"
    cd -

识别要链接的库的方法是在dmd:

中使用-v选项
dmd hello_d.d main.o -v | grep gcc