d同c对接入门
原地址
早期的d的一个设计目标就是与c对接.详细参考,因此,提供abi兼容,允许访问c标准库,并利用与c/c++编译器相同的目标文件格式/链接器.大多数d类型,甚至构直接与c构兼容,并可自由传递给c函数.当然得加上外(c).很多时候,你可以复制/粘贴c代码,然后稍微修改下,就可以编译了.同样,用c声明的也可从c端调用d.
但,d去掉了c的缺点.用数组边界检查/编译时检查内存安全来消除c的缺点.同时消除c的最大错误,混合了指针/数组.在这里有些基础
本系列,关注很容易忽略的地方,基础的可以结合官方文档(注,官方文档是个宝库)看上段.
代码,由读者来编译/链接,有对有错,理解编译器错误很重要.
c代码在窗口上用cl/dmc,其他平台上用gcc/clang.d则用dmd.窗口c编译器细节
举个在绑定c时可能发生的例子:
将展示c源码,并编译成供d链接的目标代码.先讲窗口,再讲其他平台,命令都差不多.
在同一目录,保存以下c/d代码.名字要区分,不然会覆盖.
#include <stdio.h>
void say_hello(void)
{
puts("Hello from C!");
}
上面是chello.c,下面是hello.d:
extern(C) void say_hello();
void main()
{
say_hello();
}
外(c)是个链接属性.表示按c来链接,即不混杂.
窗口直接在这里下载.点安装就一路行了.同外部目标文件链接时,关键是格式/架构(操作系统)要对.也可用dmc(在此下载)来编译c.其输出omf格式.然后,可以:
dmc -c chello.c
dmd hello.d chello.obj
hello
-c只编译.64位就得用微软的VC2019或mingw-64编译c.
cl /c chello.c
dmd -m64 hello.d chello.obj
hello
32位命令如下:
cl /c hello.c
dmd -m32mscoff hello.c chello.obj
hello
dmd的-m32表明是32位,但仍然输出omf格式.可用-m32mscoff开关来生成匹配微软的coff格式.
其他平台一般是gcc/clang.马操可用XCode在商店安装clang,林操/bsd有gcc包,用apt-get install build-essential等,德编等,参考文档.
CC为编译器命令,用gcc/clang替换.
CC -c chello.c
dmd hello.d chello.o
./hello
如果你在64位系统,安装了32位工具,你可以用-m32来生成32位工具.
现在来看陷阱,d的特征是所有平台类型的大小是固定的.短为2字节,整为4字节.永远不变.这与c不同.c对大小的规范不细致,由实现决定.当然目前现代编译器有共同约定.但不包括长/正长.
在d中长/正长始终是8字节.不变.在version(Posix)下的64位系统也是8字节.但在32位系统下,为4字节,在窗口下,32/64位的长/正长均为4字节.
现在,c99一般在stdint.h中用int32_t/int64_t来消歧.但仍可能遇见长的c库.
考虑如下c函数:
#include <limits.h>
unsigned long max_val(void)
{
return ULONG_MAX;
}
maxval.c,d的showmax1.d实现如下:
extern(C) ulong max_val();
void main()
{
import std.stdio : writeln;
writeln(max_val());
}
这依赖于c的编译器和架构,如dmc/cl(32/64)上都表现不一样.答案分别为:7316910580432895,59663353508790271,4294967295.这里正长在c都为32位,最后1个是对的,我猜是x64存储在RAX中,所以可以读进d的正长.重点是x86下两个值是垃圾,因为d端期望从32位寄存器中返回64位值.读了超过给出的值.
d运行时在core.stdc.config中,给出了c版本的长/正长(c_long/c_ulong).这两个匹配编译时c运行时实现和架构配置.然后,只需修改下声明.
import core.stdc.config : c_ulong;
extern(C) c_ulong max_val();
void main()
{
import std.stdio : writeln;
writeln(max_val());
}
showmax2.d.编译并运行.然后就对了.还在core.stdc.config中定义了c_long_double,来匹配long double来绑定c库.除了-m32mscoff这个开关,可以直接用ldc/gdc都可以.
浙公网安备 33010602011771号