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为大家提供一个学习交流各种知识的平台