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

查看完整版本: 转换C的.h文件为D模块

yidabu 2007-4-29 08:59

转换C的.h文件为D模块

转换C的.h文件为D模块知识若不分享 实在没有意义 http://www.d-programming-language-china.org 20070429点击下面网址查看原文:http://www.d-programming-language-china.org        by:        uFramer        D语言论坛 http://www.d-programming-language-china.org        from:        http://www.digitalmars.com/d/htomodule.html        version:        基于DMD 1.014        尽管 D 不能直接编译 C 的源代码,但它可以同 C 代码很好的衔接,可以同 C 目标文件连接,还可以调用 DLL 中的 C 函数。C 代码的接口通常位于 C 的 .h 文件中。所以,同 C 代码衔接的关键就在于将 C .h 文件转换为 D 模块。事实证明,这个工作很难采用机械的方法完成,必须有人加以判断。下面就是执行这种转换的一些指导。Preprocessor预处理器        .h files can sometimes be a bewildering morass of layers of macros, #include files, #ifdef's, etc. D doesn't include a text preprocessor like the C preprocessor, so the first step is to remove the need for it by taking the preprocessed output. For DMC (the Digital Mars C/C++ compiler), the command:        [Copy to clipboard] [ - ]CODE:                                dmc -c program.h -e -l                will create a file program.lst which is the source file after all text preprocessing.        Remove all the #if, #ifdef, #include, etc. statements.Linkage链接        通常,象下面这样将整个模块包起来:        [Copy to clipboard] [ - ]CODE:                                extern (C)                {                     /*...文件内容...*/                }                会使代码采用 C 的链接风格。Types型别        可以用简单的全局替换重命名C型别到D的型别。        下面是一个32位C代码的型别对应表。( 本文出处: http://www.d-programming-language-china.org )                Mapping C type to D type                C type        D type                long double        real                unsigned long long        ulong                long long        long                unsigned long        uint                long        int                unsigned        uint                unsigned short        ushort                signed char        byte                unsigned char        ubyte                wchar_t        wchar or dchar                bool        bool, byte, int                size_t        size_t                ptrdiff_t        ptrdiff_t        NULL        应该使用 NULL 宏或者 ((void*)0) 来代替 null 。Numeric Literals数值文字量        删除所有'L'或'l'数值文字量后缀,通常C的long对应于D的int.'LL'后缀应该用'L'来代替。所有'u'后缀不用改。String Literals字符串文字量        在多数情况下可以直接移除'L'前缀,需要时D会隐式转换到宽字符。当然也可以这样替换:        [Copy to clipboard] [ - ]CODE:                                L"string"                替换成:        [Copy to clipboard] [ - ]CODE:                                "string"w    // for 16 bit wide characters                "string"d    // for 32 bit wide characters        Macros宏        象这样的宏:( 本文出处: http://www.d-programming-language-china.org )        [Copy to clipboard] [ - ]CODE:                                #define FOO    1                #define BAR    2                #define ABC    3                #define DEF    40                可以被替换成:        [Copy to clipboard] [ - ]CODE:                                enum                {    FOO = 1,                    BAR = 2,                    ABC = 3,                    DEF = 40                }                或者:        [Copy to clipboard] [ - ]CODE:                                const int FOO = 1;                const int BAR = 2;                const int ABC = 3;                const int DEF = 40;                象这样函数风格的宏:        [Copy to clipboard] [ - ]CODE:                                #define MAX(a,b) ((a) < (b) ? (b) : (a))                可以被替换成:        [Copy to clipboard] [ - ]CODE:                                int MAX(int a, int b) { return (a < b) ? b : a; }                The functions, however, won't work if they appear inside static initializers that must be evaluated at compile time rather than runtime. To do it at compile time, a template can be used:( 本文出处: http://www.d-programming-language-china.org )        [Copy to clipboard] [ - ]CODE:                                #define GT_DEPTH_SHIFT    (0)                #define GT_SIZE_SHIFT    (8)                #define GT_SCHEME_SHIFT (24)                #define GT_DEPTH_MASK    (0xffU << GT_DEPTH_SHIFT)                #define GT_TEXT    ((0x01) << GT_SCHEME_SHIFT)                                /* Macro that constructs a graphtype */                #define GT_CONSTRUCT(depth,scheme,size) \                    ((depth) | (scheme) | ((size) << GT_SIZE_SHIFT))                                /* Common graphtypes */                #define GT_TEXT16    GT_CONSTRUCT(4, GT_TEXT, 16)                对应的D版本是这样的:        [Copy to clipboard] [ - ]CODE:                                const uint GT_DEPTH_SHIFT    = 0;                const uint GT_SIZE_SHIFT    = 8;                const uint GT_SCHEME_SHIFT = 24;                const uint GT_DEPTH_MASK    = 0xffU << GT_DEPTH_SHIFT;                const uint GT_TEXT    = 0x01 << GT_SCHEME_SHIFT;                                // Template that constructs a graphtype                template GT_CONSTRUCT(uint depth, uint scheme, uint size)                {                 // notice the name of the const is the same as that of the template                 const uint GT_CONSTRUCT = (depth | scheme | (size << GT_SIZE_SHIFT));                }                                // Common graphtypes                const uint GT_TEXT16 = GT_CONSTRUCT!(4, GT_TEXT, 16);        Declaration Lists声明列表        D只允许同类型的声明列表,因此:( 本文出处: http://www.d-programming-language-china.org )        [Copy to clipboard] [ - ]CODE:                                int *p, q, t[3], *s;                应该写成这样:        [Copy to clipboard] [ - ]CODE:                                int* p, s;                int q;                int[3] t;        Void Parameter Lists空参数列表        空参数的函数:        [Copy to clipboard] [ - ]CODE:                                int foo(void);                在D里这样写:( 本文出处: http://www.d-programming-language-china.org )        [Copy to clipboard] [ - ]CODE:                                int foo();        Const Type Modifiers        Const 类型修饰符        D has const as a storage class, not a type modifier. Hence, just drop any const used as a type modifier:        [Copy to clipboard] [ - ]CODE:                                void foo(const int *p, char *const q);                [Copy to clipboard] [ - ]CODE:                                void foo(int* p, char* q);        Extern Global C Variables外部全局C变量        D里声明一个变量,也就是定义了一个变量。如果也在链接进来的C object文件里定义了,就是一个多次定义错误。要解决这个问题,可以使用外部存储类。例如有一个C头文件foo.h:        [Copy to clipboard] [ - ]CODE:                                struct Foo { };                struct Foo bar;                可以用D模块foo.d来代替:        [Copy to clipboard] [ - ]CODE:                                struct Foo { }                extern (C)                {                    extern Foo bar;                }        Typedef        在 D 中 alias 等价于 C 中的 typedef :( 本文出处: http://www.d-programming-language-china.org )        [Copy to clipboard] [ - ]CODE:                                typedef int foo;                变为:        [Copy to clipboard] [ - ]CODE:                                alias int foo;        Structs结构        C的结构:        [Copy to clipboard] [ - ]CODE:                                typedef struct Foo                {    int a;                    int b;                } Foo, *pFoo, *lpFoo;                替换成:        [Copy to clipboard] [ - ]CODE:                                struct Foo                {    int a;                    int b;                }                alias Foo* pFoo, lpFoo;        Struct Member Alignment结构成员对齐        A good D implementation by default will align struct members the same way as the C compiler it was designed to work with. But if the .h file has some #pragma's to control alignment, they can be duplicated with the D align attribute:        [Copy to clipboard] [ - ]CODE:                                #pragma pack(1)                struct Foo                {                    int a;                    int b;                };                #pragma pack()                becomes:        [Copy to clipboard] [ - ]CODE:                                struct Foo                {                    align (1):                    int a;                    int b;                }        Nested Structs嵌套结构        [Copy to clipboard] [ - ]CODE:                                struct Foo                {                    int a;                    struct Bar                    {                    int c;                    } bar;                };                                struct Abc                {                    int a;                    struct                    {                    int c;                    } bar;                };                改成D是这样的:        [Copy to clipboard] [ - ]CODE:                                struct Foo                {                    int a;                    struct Bar                    {                    int c;                    }                    Bar bar;                }                                struct Abc                {                    int a;                    struct                    {                    int c;                    }                }        __cdecl, __pascal, __stdcall        [Copy to clipboard] [ - ]CODE:                                int __cdecl x;                int __cdecl foo(int a);                int __pascal bar(int b);                int __stdcall abc(int c);                转换成:        [Copy to clipboard] [ - ]CODE:                                    extern (C) int x;                    extern (C) int foo(int a);                    extern (Pascal) int bar(int b);                    extern (Windows) int abc(int c);        __declspec(dllimport)        [Copy to clipboard] [ - ]CODE:                                __declspec(dllimport) int __stdcall foo(int a);                转换成:        [Copy to clipboard] [ - ]CODE:                                export extern (Windows) int foo(int a);        __fastcall        Unfortunately, D doesn't support the __fastcall convention. Therefore, a shim will be needed, either written in C:        [Copy to clipboard] [ - ]CODE:                                int __fastcall foo(int a);                                int myfoo(int a)                {                    return foo(int a);                }                and compiled with a C compiler that supports __fastcall and linked in, or compile the above, disassemble it with obj2asm and insert it in a D myfoo shim with inline assembler.        http://www.digitalmars.com/ctg/obj2asm.html        http://digitalmars.com/d/iasm.html( 本文出处: http://www.d-programming-language-china.org )( lastupdate:20070429 最新文章请访问http://www.d-programming-language-china.org )关于一大步成功社区:yidabu提倡在交流中学习,在分享中提高收集感兴趣的知识,写下心得,通过网络与别人一起分享理解一点就实践一步,收获什么就分享什么,成功就是这样一点点一步步累积起来的网络只是一个工具,只有自己身心提高才是实实在在的。d-programming-language-china.org为大家提供一个学习交流各种知识的平台
页: [1]
查看完整版本: 转换C的.h文件为D模块