【问题标题】:How to link a D library in a C program?如何在 C 程序中链接 D 库?
【发布时间】:2016-02-04 16:37:53
【问题描述】:

我想从 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 函数。如果我这样做,我会在运行主程序时遇到分段错误。 请告诉我如何将 d 函数(利用标准 d 库)链接到 c 程序中。

【问题讨论】:

  • “/home/walter/tmp/libdll.so”只是您之前链接到的说明中构建的示例共享库。
  • 当我在 Ubuntu 14.04 上使用 dmd v2.068.0 尝试时,您的示例有效。
  • 我确认该示例适用于 Archlinux,DMD v2.070.0

标签: c linux linker shared-libraries d


【解决方案1】:

分段错误和链接错误的原因是缺少所需的库。这可以通过链接它们来解决。此外,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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-09
    • 2013-07-12
    • 1970-01-01
    • 2013-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多