我想调用使用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程序中。
答案 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