D语言中国主页  D语言编辑器SciTE4D   DWin库 D语言官方网站
D语言编译器1.x最新版 OpenSource   Tango   webnews  Wiki

查看完整版本: 28 D语言 对C的接口 Interfacing to C

yidabu 2007-4-26 16:12

28 D语言 对C的接口 Interfacing to C

28 D语言 对C的接口 Interfacing to C知识若不分享 实在没有意义 http://www.d-programming-language-china.org 20070426点击下面网址查看原文:http://www.d-programming-language-china.org        by:        uFramer        http://www.d-programming-language-china.org        from:        http://www.digitalmars.com/d/interfaceToC.html        version:        基于D 1.013        (Apr 19, 2007)        按照设计,D 应该同目标系统上的 C 协作良好。D 依赖于目标环境上的 C 运行时库,这多少补偿了缺少标准虚拟机的一些缺陷。将现有的 C API 用 D 重写或用 D 封装意义不大。直接调用它们不是要容易得多?!        如果采用了同 C 编译器相同的数据类型、内存分布和函数调用/返回指令序列,就可以这样做。Calling C Functions调用 C 函数        D 可以直接调用 C 函数。不需要封装函数、参数变换,C 函数也不需要放到单独的 DLL 中。        C 函数必须被声明为采用 "C" 调用约定,例如:        [Copy to clipboard] [ - ]CODE:                                extern (C) int strcmp(char* string1, char* string2);                然后就可以在 D 代码中很自然的调用它们了:        [Copy to clipboard] [ - ]CODE:                                import std.string;                int myDfunction(char[] s)                {                    return strcmp(std.string.toStringz(s), "foo");                }                需要注意以下几点:        D 知道 C 函数名的变换规则及函数的调用/返回指令序列。        C 函数不能被另一个同名的 C 函数重载。        D 中没有如 __cdecl、__far、__stdcall、__declspec 或者如此之类的 C 类型修饰符。这些功能由“特征”来实现,如 extern (C) 。        D 中没有 const 或 volatile 类型修饰符。如果要声明一个用到这些类型修饰符的 C 函数,只需要从声明中移除这些关键字即可。        D 中的字符串不以 0 结尾。参见“数据类型兼容性”。 However, string literals in D are 0 terminated.        相应地,只要 D 函数采用了同 C 编译器兼容的特征,最可能的是 extern (C),C 代码也可以调用 D 函数:        [Copy to clipboard] [ - ]CODE:                                // myfunc() 可以被任何 C 函数调用                extern (C)                {                    void myfunc(int a, int b)                    {                    ...                    }                }        Storage Allocation存储分配        C 代码通过调用 malloc() 和 free() 显示地管理内存。D 使用 D 垃圾收集程序分配内存,所以不需要显式地释放内存。        D 仍然可以使用 c.stdlib.malloc() 和 c.stdlib.free() 显式地分配和释放内存,可用于链接那些需要 malloc 缓冲的 C 函数之类的情况。        如果指向垃圾收集程序分配的内存的指针被传递给 C 函数,必须确保这份内存不会在使用它的 C 函数退出之前被内存收集程序回收。要达到这个目的,可以:( 本文出处: http://www.d-programming-language-china.org )        使用 c.stdlib.malloc() 创建一份数据的副本,把该副本传递给 C 函数。        将指针放在堆栈上(作为参数或者自动变量),因为垃圾收集程序会扫描堆栈。        将指向它的指针放在静态数据段,因为垃圾收集程序会扫描静态数据段。        使用 gc.addRoot() 或者 gc.addRange() 将指针交由垃圾收集程序管理。        就算是指向所分配内存块内部的指针也足以让 GC 知道对象正在使用;也就是,不一定要需要维护指向所分配内存开始处的指针。        垃圾收集程序不会扫描不是通过 D Thread 接口创建的线程的堆栈,也不会扫描其它 DLL 中的数据段等。( 本文出处: http://www.d-programming-language-china.org )Data Type Compatibility数据类型兼容性                        D type        C type                        void        void                        bit        no equivalent                        byte        signed char                        ubyte        unsigned char                        char        char (chars are unsigned in D)                        wchar        wchar_t (when sizeof(wchar_t) is 2)                        dchar        wchar_t (when sizeof(wchar_t) is 4)                        short        short                        ushort        unsigned short                        int        int                        uint        unsigned                        long        long long                        ulong        unsigned long long                        float        float                        double        double                        real        long double                        ifloat        float _Imaginary                        idouble        double _Imaginary                        ireal        long double _Imaginary                        cfloat        float _Complex                        cdouble        double _Complex                        creal        long double _Complex                        struct        struct                        union        union                        enum        enum                        class        no equivalent                        type*        type *                        type[dim]        type[dim]                        type[dim]*        type(*)[dim]                        type[]        no equivalent                        type[type]        no equivalent                        type function(parameters)        type(*)(parameters)                        type delegate(parameters)        no equivalent                                                -->                对于大多数的 32 位 C 编译器来说,上述对应关系是成立的。C 标准并不约束类型的大小,所以使用这种对应关系时要格外小心。Calling printf()        调用 printf()        主要的问题是 printf 格式指示符如何匹配对应的 D 数据类型。尽管按照设计,printf 只能处理以 0 结尾的字符串,不能处理 D 的char 动态数组,但事实证明,由于 D 动态数组的结构是{长度,指向数据的指针},printf 的 %.*s 格式工作的很好:        [Copy to clipboard] [ - ]CODE:                                void foo(char[] string)                {                    printf("my string is: %.*s\n", string);                }                机敏的读者会注意到 printf 格式字符串文字量并不以‘\0’结尾。这是因为如果字符串文字量不是数据结构的初始值,就会在结尾处存储一个辅助的‘\0’。( 本文出处: http://www.d-programming-language-china.org )        An improved D function for formatted output is std.stdio.writef().Structs and Unions结构和联合        D 的结构和联合同 C 中的相似。        C 代码通常使用命令行选项或者各种实现提供的 #pragma 指令指定结构的对齐或者紧缩方式。D 支持与 C 编译器规则对应的显式的对齐特征。可以先查看 C 代码是如何对齐的,然后据此显式地设置 D 结构的对齐方式。        D 不支持位域。如果需要,可以使用移位和 mask 操作进行模拟。Interfacing to C++对 C++ 的接口        D 不提供对 C++ 的接口。但是因为 D 提供了对 C 的接口,所以可以访问采用 C 链接的 C++ 函数。        D 的类对象同 C++ 的类对象不兼容。( lastupdate:20070426 最新文章请访问http://www.d-programming-language-china.org )关于一大步成功社区:yidabu提倡在交流中学习,在分享中提高收集感兴趣的知识,写下心得,通过网络与别人一起分享理解一点就实践一步,收获什么就分享什么,成功就是这样一点点一步步累积起来的网络只是一个工具,只有自己身心提高才是实实在在的。d-programming-language-china.org为大家提供一个学习交流各种知识的平台
页: [1]
查看完整版本: 28 D语言 对C的接口 Interfacing to C