﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-qiezi的学习园地-随笔分类-D</title><link>http://www.cppblog.com/cpunion/category/320.html</link><description>AS/C/C++/D/Java/JS/Python/Ruby</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 13:00:17 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 13:00:17 GMT</pubDate><ttl>60</ttl><item><title>[D语言] D语言数组</title><link>http://www.cppblog.com/cpunion/archive/2006/10/07/13418.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sat, 07 Oct 2006 08:21:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/10/07/13418.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/13418.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/10/07/13418.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/13418.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/13418.html</trackback:ping><description><![CDATA[先看一段代码：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">];<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    c.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br /><br />    c.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    c.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br />}</span></div><br /><br />它输出结果如下：<br /><br />B7D19FB0, B7D19FB4, B7D19FB8,<br />B7D19FB0, B7D19FB4,<br />B7D19FB0, B7D19FB4, B7D19FB8,<br />B7D1CFA0, B7D1CFA4, B7D1CFA8, B7D1CFAC,<br /><br />可以看到前3行地址相同，后面一行地址不同。为什么？<br /><br />D语言的数组分配是内存紧凑的，当减小数组长度减小时，只需要修改切片大小而不需要重新分配。当长度变大时，也会检查原来的缓冲区是否够大，以确定是否需要重新分配空间。注意第2次操作时把长度恢复为原来大小时，并非真的恢复了原来的状态，后面长出来的元素会被初始化为默认值。<br /><br />再来看一个：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">];<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] d </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> c;<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; d){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    d.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">;<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; d){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    d.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">;<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; d){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br />}</span></div><br />在执行int[] d = c;以后，d的确是和c共享了存储区。不过在改变d的长度以后，它就和c分道扬镳了。所以int[] d = c不能理解为d是一个指向c的引用，它实际上创建了一个新的数组对象，但并不拷贝数组元素，它和int[] d = c[0 .. length]是等价的，都是数组切片操作。<br /><br />这个问题让我困惑不已。比如你用char[]表示一个单词，用char[][]表示一行，char[][][]表示多行。如何引用这个单词？你当然可以每次使用lines[i][j]，但如果处理步骤很多，这会不会看起来很头大？<br /><br />看上去应该这样使用：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[][][] lines;<br /></span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[][] line </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> lines[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">];<br />line.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> line.length </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />line[length </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">] </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;</span></div><br />可惜根据前面的结论，这将无法影响到lines。如果找不到一个引用类型指向数组，有时候使用起来还真是很麻烦。看起来把Line/Word包装成类是个勉强凑合的主意。。。<img src ="http://www.cppblog.com/cpunion/aggbug/13418.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-10-07 16:21 <a href="http://www.cppblog.com/cpunion/archive/2006/10/07/13418.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] Array slicing</title><link>http://www.cppblog.com/cpunion/archive/2006/10/06/13393.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 06 Oct 2006 01:35:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/10/06/13393.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/13393.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/10/06/13393.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/13393.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/13393.html</trackback:ping><description><![CDATA[数组slicing操作并不复制数据。<br /><br />指针的slicing操作和数组slicing语意是相同的。<br /><br />通过slicing生成D数组，比原来直接使用指针的好处是可以有边界检查。<br /><br />最近刚好犯了这个错误，在使用freetype时，render出来的位图数据直接使用slicing生成数组保存起来。由于slicing并不复制数据，这样后面的render操作会覆盖前面的数据，所以我保存的数组其实都指向同一个缓冲区。当释放face对象时，缓冲区也没了，再访问恐怕要段错误了。<br /><br />这个是D文档中明确描述了的，我却花了点时间才排除这个错误，写下来记录之～<br /><img src ="http://www.cppblog.com/cpunion/aggbug/13393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-10-06 09:35 <a href="http://www.cppblog.com/cpunion/archive/2006/10/06/13393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] DMD 0.168发布</title><link>http://www.cppblog.com/cpunion/archive/2006/10/05/13362.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 05 Oct 2006 01:23:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/10/05/13362.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/13362.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/10/05/13362.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/13362.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/13362.html</trackback:ping><description><![CDATA[新特性：<br />1、给委托增加ptr属性，指向委托所绑定的对象。<br />这是一个语法糖，dg.ptr被转化为cast(void*)dg，它只能作右值，所以除了能读取它以外，在语法上禁止对它赋值。要想把委托绑定到不同的对象，你只能自己实现：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Foo{<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> foo;<br /></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> foo){<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.foo </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> foo;<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> bar(){<br />        writefln(foo);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br /><br />    alias </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">delegate</span><span style="color: rgb(0, 0, 0);">() DG;<br />    DG dg </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)).bar;<br /><br />    Foo[</span><span style="color: rgb(0, 0, 0);">10</span><span style="color: rgb(0, 0, 0);">] foos;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i, inout Foo foo; foos){<br />        foo </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(i);<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);"> ptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">dg;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(Foo foo; foos){<br />        </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">ptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)foo;<br />        dg();<br />    }<br />}</span></div><br />这种方式也不是我们所希望的，一般来说委托绑定到多个对象时，因为是取到某成员函数指针，再进行绑定。比如模拟一个ActiveSupport所扩展的一个ruby.Array#map用法：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">import std.stdio;<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Foo{<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> foo;<br /></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> foo){<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.foo </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> foo;<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> bar(){<br />        writefln(foo);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Array(T){<br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">:<br />    T[] data;<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(T[] data){<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.data </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> data[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> .. length];<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> map(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> function() func){<br />        </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">delegate</span><span style="color: rgb(0, 0, 0);">() dg;<br />        </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);"> funcPtr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">dg </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />        </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">funcPtr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> func;<br />        </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);"> ptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">dg;<br />        </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(T v; data){<br />            </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">ptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)v;<br />            dg();<br />        }<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    auto arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Array</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">(Foo)([</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">), </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">), </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">)]);<br />    arr.map(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">Foo.bar);<br />}</span></div><br />是的，delegate内部保存了2个指针，所以我们可以容易地hack它。<br /><br />[注：上面的main函数中数组直接量赋给栈对象也是这个版本中新增的内容，显然只能用于static对象是很鸡肋的。这里简单带过不提。]<br /><br />[注：上面这个map的模拟并不是ActiveSupport的map扩展的全部用途，那个map还是收集返回值，这里只演示调用语法。ActiveSupport中扩展的map调用语法是map(&amp;:to_s)，就可以收集到数组中所有元素调用to_s后的返回值。]<br /><br />2、给内嵌内的实例增加outer属性，指向外层对象。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">import std.stdio;<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Outer{<br />    </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Inner{}<br /><br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(){<br />        Inner inner </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Inner;<br />        inner.outer.foo();<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> foo(){<br />        writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    Outer outer </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Outer;<br />}</span></div><br />这个特性可能应用并不是很广吧。<br /><br />3、mixin多个析构函数。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">template A(){<br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(){<br />    }<br />    </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(){<br />        writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">A::~A()</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />}<br /><br />template B(){<br />    </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(){<br />        writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">B::~B()</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> C{<br />    mixin A;<br />    mixin B;<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    C c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> C;<br />    delete c;<br />}</span></div><br />这些析构函数会和mixin相反的顺序执行。我不明白的是，为什么不让mixin多个构造函数？为何不让这些构造函数晚于被mixin的类（上面的C类）的构造函数，并按mixin进来的顺序执行？<br /><img src ="http://www.cppblog.com/cpunion/aggbug/13362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-10-05 09:23 <a href="http://www.cppblog.com/cpunion/archive/2006/10/05/13362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] DMD 0.167发布</title><link>http://www.cppblog.com/cpunion/archive/2006/09/19/12721.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Tue, 19 Sep 2006 12:16:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/19/12721.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/12721.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/09/19/12721.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/12721.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/12721.html</trackback:ping><description><![CDATA[这个版本实现了计划已久的数组直接量。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">stdio;<br /><br />void main(){<br />  {<br />    static </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">];<br />    writefln(typeid(typeof(arr[</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">])));<br />    writefln(arr);<br />  }<br />  {<br />    static float[] arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [1f</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">];<br />    writefln(typeid(typeof(arr[</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">])));<br />    writefln(arr);<br />  }<br />  {<br />    static char[][] arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">1</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">2</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">3</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">4</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">5</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">];<br />    writefln(typeid(typeof(arr[</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">])));<br />    writefln(arr);<br />  }<br />}</span></div><br />数组类型由第1个元素类型决定，类型不匹配将会产生编译错误。<br /><br />接着是多维数组：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">stdio;<br /><br />void main(){<br />  static </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[][] arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [[</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">6</span><span style="color: rgb(0, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(128, 0, 0);">7</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">]];<br />  </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] </span><span style="color: rgb(0, 0, 255);">sub</span><span style="color: rgb(0, 0, 0);">; arr){<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; </span><span style="color: rgb(0, 0, 255);">sub</span><span style="color: rgb(0, 0, 0);">){<br />      writefln(i);<br />    }<br />  }<br />}</span></div><br /><br />另一个特性是更强的typedef。原有的typedef强类型在某些情况下会产生混乱。<br /><br />下面的代码摘自 http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&amp;group=digitalmars.D.bugs&amp;artnum=3843<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">stdio;<br /><br />typedef </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> Int1;<br />typedef </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> Int2;<br /><br />void show(Int1 v) {<br />     writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Int1: %d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> v);<br />}<br /><br />void show(Int2 v) {<br />     writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Int2: %d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> v);<br />}<br /><br />void show(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i) {<br />     writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">int: %d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> i);<br />}<br /><br />void show(long l) {<br />     writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">long: %d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> l);<br />}<br /><br />void main() {<br />     Int1 value1 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">42</span><span style="color: rgb(0, 0, 0);">;<br />     Int2 value2 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">69</span><span style="color: rgb(0, 0, 0);">;<br /><br />     show(value1 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value2);<br />     show(value2 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value1);<br />     show(</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> value1);<br />     show(value1 </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">);<br />     show(value1 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value1);<br />     show(value2 </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> value2);<br />     show(value1 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">);<br />     show(</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value2);<br /><br />     long l </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">23</span><span style="color: rgb(0, 0, 0);">;<br />     show(value1 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> l);<br />     show(l </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value2);<br /><br />     short s </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">105</span><span style="color: rgb(0, 0, 0);">;<br />     show(s </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value1);<br />     show(value2 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> s);<br />}</span></div><br />如上面代码所示。typedef定义出来的类型和原有类型的相同形式重载函数可以共存，这可以完成更强类型的重载，C＋＋的重载还不能实现这个。<br /><br />这个强类型的typedef好像原本就支持，大概是运算结果类型比较模糊。<br /><br />好处是显页易见的。比如有一个Time和TimeInterval类型，它用来表示绝对时间或相对时间间隔；另有一个输出函数用来显示结果。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">stdio;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">string;<br /><br />typedef long </span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);">;<br />typedef long TimeInterval;<br /><br />void output(</span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);"> t){<br />  writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Time: </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> toString(cast(long)t));<br />}<br />void output(TimeInterval t){<br />  writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Interval: </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> toString(cast(long)t));<br />}<br />void main(){<br />  </span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">time</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(128, 0, 0);">100</span><span style="color: rgb(0, 0, 0);">;<br />  TimeInterval interval </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(TimeInterval)</span><span style="color: rgb(128, 0, 0);">100</span><span style="color: rgb(0, 0, 0);">;<br />  output(</span><span style="color: rgb(0, 0, 255);">time</span><span style="color: rgb(0, 0, 0);">);<br />  output(interval);<br />}</span></div><br />是的，使用上麻烦了很多，因为我们试图用一个数值类型去表示多个矢量类型。<br /><br />这里Time time = cast(Time)100不再只是100这个简单的数值，它还携带了Time这个类型。TimeInterval interval = cast(TimeInterval)100也不只是100这个数值，我们给它赋予了时间间隔的含义。<br /><br />还可以想像得更开阔一些，用它定义时间、长度、面积、加速度、速度、温度等，重载一些计算函数（可惜D还不支持全局操作符重载），这样就方便完成一些物理量的运算了，而且类型得到检查，速度加一个整数值结果还是速度，速度乘时间得到的是长度，时间减时间得到的是时间间隔，速度加时间将产生编译错误。。。。。。神奇的是这些类型可能都是一些简单类型，我相信它至少可以保证运行效率不会太低。当然你用C＋＋类也可以完成这些，并且利用编译器优化让它的效率保持最高，甚至内联的结果就是简单类型的运算，我还是更愿意使用这简单的类型来typedef。当然这可能需要写大量重复的函数重载形式，没有关系，我想使用模板和mixin应该可以简化这一过程，而且会有相当多的家伙们愿意使用这种麻烦的形式来获得更“正确”的编译检查。<br /><br /><br />所以说，D语言的typedef的意义其实就是实现了矢量类型。<br /><br /><hr size="2" width="100%" /><br />又多想了一点。<br /><br />强类型要，语法糖也应该要。是不是可以借鉴一下ruby的语法，实现这种调用呢？<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">Length</span><span style="color: rgb(0, 0, 0);"> l </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">cm;<br />l </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">m;<br /></span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);"> t </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">now;<br />TimeInterval i </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">hours;</span></div><br />免去了一些初始化的麻烦。<br /><img src ="http://www.cppblog.com/cpunion/aggbug/12721.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-19 20:16 <a href="http://www.cppblog.com/cpunion/archive/2006/09/19/12721.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] DMD 0.166发布</title><link>http://www.cppblog.com/cpunion/archive/2006/09/01/11938.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 01 Sep 2006 14:34:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/01/11938.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/11938.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/09/01/11938.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/11938.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/11938.html</trackback:ping><description><![CDATA[这一版本在强大的民意压力之下取消了上一版的“隐式转换表达式为委托”这一特性，取而代之的是一个lazy关键字。<br /><br />取消的理由是这个转换太隐晦了，最好是显式地标示出这种转换，所以引入一个lazy关键字。D语言还在发展中，很多特性都在尝试，这种修改也不是第一次了。<br /><br />首先看看这个lazy。<br /><br />上一版实现了这样一个特性：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> log(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[] </span><span style="color: rgb(0, 0, 255);">delegate</span><span style="color: rgb(0, 0, 0);">() msg){<br />  writefln(msg());<br />}<br /><br />log(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hello, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Li Jie! \n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Welcome!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);</span></div><br />log的参数被隐式转化为一个委托，这样只有用到这个值的时候才真正求值。<br /><br />由于这种隐式转化很容易形成陷阱，所以这一版改为一个lazy关键字，看起来要简洁一些了：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> log(lazy </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[]  msg){<br />  writefln(msg);<br />}<br /><br />log(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hello, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Li Jie! \n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Welcome!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);</span></div><br />log函数中使用msg这个变量就会调用那个隐式的委托，要注意的是每次取msg的值都会执行这个委托，所以我觉得这个陷阱更大了，当然它把陷阱丢给编写代码的人，而不是使用代码的人，所以好坏还无从分辨。<br /><br />下面这点代码可以演示这个小陷阱：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> foo(lazy </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a){<br />  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> b </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">;<br />  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> d </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">;<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> bar(){<br />  writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Call bar()</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />  </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">12</span><span style="color: rgb(0, 0, 0);">;<br />}<br /><br />foo(bar());</span></div><br />看起来bar好像会执行一次，实际上这段代码会打印出3行"Call bar()"，原来使用委托还可以看到一个显式的函数调用呢。<br /><br />另一个member templates特性未见到文档，猜想大概是支持成员函数模板吧。<br /><img src ="http://www.cppblog.com/cpunion/aggbug/11938.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-01 22:34 <a href="http://www.cppblog.com/cpunion/archive/2006/09/01/11938.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] DMD 0.165发布</title><link>http://www.cppblog.com/cpunion/archive/2006/08/21/11517.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 21 Aug 2006 05:24:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/08/21/11517.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/11517.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/08/21/11517.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/11517.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/11517.html</trackback:ping><description><![CDATA[前几个版本主要是修正BUG，并没有多少新特性，这个版本终于增加了一个“隐式转换表达式到委托”，这个特性也使“懒惰(或延迟)求值”成为可能。<br /><br />详细信息可见：<a href="http://www.digitalmars.com/d/lazy-evaluation.html">http://www.digitalmars.com/d/lazy-evaluation.html</a><br /><br />它首先解决了一个存在于java中的日志问题，java里面一个写日志标准格式如下：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (log.isLoggable(Level.INFO)) {<br />  log.info(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">aaaa</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />}</span></div><br />因为log.info的参数求值可能影响性能，所以使用这种繁琐的方式来降低关闭日志时的性能开销。<br /><br />C/C++使用宏来解决这个问题，唯一的问题是修改日志级别会导致项目必须重编译。<br /><br />[注：指的是用宏来定义日志级别的方式，使用其它动态修改日志级别的方式对性能要求很高的项目来说可能不可接受]<br /><br />D语言使用另一种方式来解决，首先要用到“表达式到委托的隐式转换”，下面是委托作为参数时的使用方法：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> foo(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">() dg){<br />  writefln(dg());<br />}<br /><br />foo( </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] (){<br />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, World</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br />  }<br />);</span></div><br />因为这个委托并不需要参数，而返回值可以推导，所以在早先的一个版本里，D允许我们简化这个过程：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> foo(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">() dg){<br />  writefln(dg());<br />}<br /><br />foo({</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, World</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;});</span></div><br />DMD 0.165允许我们更进一步：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> foo(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">() dg){<br />  writefln(dg());<br />}<br /><br />foo(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, World</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div><br />这个字符串参数会被隐式转换成一个委托。<br /><br />现在可以用一样的方法处理日志，在没有宏的系统中，日志函数一般格式如下：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> log(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] message)<br />{<br />    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (logging)<br />    fwritefln(logfile, message);<br />}</span></div><br />为了让它使用懒惰求值这个特性，这里把这个函数的参数改为委托：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> log(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">() dg)<br />{<br />    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (logging)<br />    fwritefln(logfile, dg());<br />}</span></div><br />从上面提到的内容我们知道使用它也很简单：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">log(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">My name is </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">~</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Li Jie</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div><br />这个参数的求值就是在log函数里面完成的。<br /><br />当然委托会增加一些开销，在上面这个例子中，这个开销是在日志打开时执行委托所带来的，它增加了一次委托调用的开销，不过好在打开日志功能时，其它方面的开销远大过委托调用。关闭日志时，它不会带来开销，它只是把字符串指针压栈改为委托指针压栈。<img src ="http://www.cppblog.com/cpunion/aggbug/11517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-08-21 13:24 <a href="http://www.cppblog.com/cpunion/archive/2006/08/21/11517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] 用D语言编写Ruby扩展</title><link>http://www.cppblog.com/cpunion/archive/2006/08/19/11427.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 18 Aug 2006 22:17:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/08/19/11427.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/11427.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/08/19/11427.html#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/11427.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/11427.html</trackback:ping><description><![CDATA[<p>Ruby语言的官方解释程序是使用C语言开发的，一般用C语言来编写扩展。D语言和C语言是二进制兼容的，所以可以使用D语言编写Ruby扩展。<br /></p>
		<p>
				<strong>
						<br />一、移植C库到D的一般过程</strong>
		</p>
		<p>C使用头文件来处理符号依赖，在D里面链接外部库文件时，要使用extern (C)声明来引入符号，这是一个转换过程。</p>
		<p>如何转换一个C头文件到D文件？D文档的htomodule.html有详尽说明。一般的转换过程如下：
</p>
		<p>1、运行预处理程序处理掉头文件里面的宏。</p>
		<p>2、删除经过预处理以后的多余信息。由于C的头文件包含，每个头文件经过预处理以后都会包含一些重复内容，我们需要剔除这部分内容，通过查找行号即可完成。</p>
		<p>3、转换相应声明到D声明，这一步可以使用一个c2h程序来完成。</p>
		<p>注意预处理程序处理完毕以后，宏函数以及宏定义的常量会被去除，这可能不是你想要的，所以最好的办法可能是手工转换。</p>
		<p>另一种调用是在D里面调用动态链接库，这需要你使用implib工具从动态链接库产生一个.lib导入库文件，然后生成D声明，再编译链接即可。如果是在linux下使用共享库，则只需要编写D声明文件，然后直接链接即可。<br /></p>
		<p>
				<strong>
						<br />二、调用C库</strong>
		</p>
		<p>转换完毕以后，就可以调用了。如果你只是要测试一下，就可以只声明使用过的外部函数、变量即可。</p>
		<p>例如我们要编写Programming Ruby里面的一个Ruby Extension例子，相应的D代码如下：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> test.d</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">module test;<br /><br />import ruby;<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C)<br />VALUE t_init(VALUE self)<br />{<br />  VALUE arr </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> rb_ary_new();<br />  rb_iv_set(self, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">@arr</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, arr);<br />  </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> self;<br />}<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C)<br />VALUE t_add(VALUE self, VALUE anObject)<br />{<br />  VALUE arr </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> rb_iv_get(self, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">@arr</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">);<br />  rb_ary_push(arr, anObject);<br />  </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> arr;<br />}<br /><br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C){<br /><br />VALUE cTest;<br /><br />alias VALUE(</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">func_type)();<br /><br />export </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> Init_Test()<br />{<br />  cTest </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> rb_define_class(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">Test</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, rb_cObject);<br />  rb_define_method(cTest, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">initialize</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, cast(func_type)</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">t_init, </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">);<br />  rb_define_method(cTest, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">add</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, cast(func_type)</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">t_add, </span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">);<br />}<br /><br />}  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> extern(C)</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">
						<br />
				</span>
		</div>
		<p>
				<br />和C代码很相似。由于我们只使用了几个外部函数、变量，所以只需要声明这几个符号即可：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> ruby.d</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">module ruby;<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000"> (C){<br />    alias </span>
				<span style="COLOR: #0000ff">ulong</span>
				<span style="COLOR: #000000"> VALUE;<br />    VALUE rb_cObject;<br />    VALUE rb_ary_new ();<br />    VALUE rb_ary_push (VALUE, VALUE);<br />    VALUE rb_iv_set (VALUE,  </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">, VALUE);<br />    VALUE rb_iv_get (VALUE,  </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">);<br />    VALUE rb_define_class ( </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">,VALUE);<br />    </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> rb_define_method (VALUE, </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">,VALUE(</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">)(),</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000">);<br />}<br /></span>
		</div>
		<p>
				<strong>
						<br />三、生成动态链接库(Windows DLL)或共享库(Linux so文件)</strong>
		</p>
		<p>D语言在Windows上编写DLL，除了要有D源文件以外，还要有DLL定义文件：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> test.def</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">LIBRARY         Test<br />DESCRIPTION     </span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">Test written in D</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">
						<br />
						<br />EXETYPE  NT<br />CODE            PRELOAD DISCARDABLE<br />DATA            PRELOAD SINGLE<br /></span>
		</div>
		<p>这是一个通用的格式，只是一些描述信息，因为D中可以使用export关键字导出符号，所以不需要在这里声明导出函数，只有在编写COM DLL时才会增加其它一些信息。</p>
		<p>另外由于D语言要初始化GC以及其它一些信息，所以还需要在DllMain里面调用初始化及终止代码。由于不同平台的初始化过程不完全相同，这里我简单封闭了一下不同平台的初始化代码：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> os/library.d</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">module os.library;<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C){<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> gc_init();<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> gc_term();<br />  version(Windows) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _minit();<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _moduleCtor();<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _moduleDtor();<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _moduleUnitTests();<br />  version(linux) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _STI_monitor_staticctor();<br />  version(linux) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _STI_critical_init();<br />  version(linux) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _STD_monitor_staticdtor();<br />  version(linux) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _STD_critical_term();<br />}<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C)<br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> d_init()<br />{<br />  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> writefln("Start init D runtime");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">  version(linux) _STI_monitor_staticctor();<br />  version(linux) _STI_critical_init();<br />  gc_init();<br />  version(Windows) _minit();<br />  _moduleCtor();<br />  _moduleUnitTests();<br />  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> writefln("init finished");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">}<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C)<br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> d_fini()<br />{<br />  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> writefln("Start term D runtime");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">  _moduleDtor();<br />  gc_term();<br />  version(linux) _STD_critical_term();<br />  version(linux) _STD_monitor_staticdtor();<br />  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> writefln("term finished");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">}<br /></span>
		</div>
		<p>现在可以为Windows编写初始化及终止代码：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> os/dll.d</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">module os.dll;<br /><br /></span>
				<span style="COLOR: #0000ff">private</span>
				<span style="COLOR: #000000"> import os.library;<br /></span>
				<span style="COLOR: #0000ff">private</span>
				<span style="COLOR: #000000"> import std.c.windows.windows;<br /><br />HINSTANCE g_hInst;<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000"> (Windows)<br />BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)<br />{<br />  </span>
				<span style="COLOR: #0000ff">switch</span>
				<span style="COLOR: #000000"> (ulReason)<br />  {<br />    </span>
				<span style="COLOR: #0000ff">case</span>
				<span style="COLOR: #000000"> DLL_PROCESS_ATTACH:<br />      d_init();<br />      </span>
				<span style="COLOR: #0000ff">break</span>
				<span style="COLOR: #000000">;<br /><br />    </span>
				<span style="COLOR: #0000ff">case</span>
				<span style="COLOR: #000000"> DLL_PROCESS_DETACH:<br />      d_fini();<br />      </span>
				<span style="COLOR: #0000ff">break</span>
				<span style="COLOR: #000000">;<br /><br />    </span>
				<span style="COLOR: #0000ff">case</span>
				<span style="COLOR: #000000"> DLL_THREAD_ATTACH:<br />    </span>
				<span style="COLOR: #0000ff">case</span>
				<span style="COLOR: #000000"> DLL_THREAD_DETACH:<br />      </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> Multiple threads not supported yet</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">      </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">false</span>
				<span style="COLOR: #000000">;<br />  }<br />  g_hInst</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">hInstance;<br />  </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">true</span>
				<span style="COLOR: #000000">;<br />}<br /></span>
		</div>
		<p>由于Linux共享库并没有标准的入口函数(或是我不知道它)，这里使用gcc扩展的初始、终止代码，不过是以C语言实现的：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> os/so.c</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">ruby.h</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">static</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> so_init(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">) __attribute__((constructor));<br /></span>
				<span style="COLOR: #0000ff">static</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> so_fini(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">) __attribute__((destructor));<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> d_init(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">);<br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> d_fini(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">);<br /><br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> so_init(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">)<br />{<br />  d_init();<br />}<br /><br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> so_fini(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">)<br />{<br />  d_fini();<br />}<br /></span>
		</div>
		<p>现在可以尝试编译链接，在Linux上编译命令如下：<br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">gcc </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">o os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">so.o </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">c os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">so.c </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">I </span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">usr</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">lib</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">ruby</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">1.8</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">i686</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">linux <br />gdc </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">o Test.so test.d os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">so.o ruby.d </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">shared </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">fPIC </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">lruby</span>
		</div>
		<p>你可以在irb下测试：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">require </span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">Test</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">
						<br />test </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> Test.</span>
				<span style="COLOR: #0000ff">new</span>
				<span style="COLOR: #000000">
						<br />test.add(</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">)<br />test.add(</span>
				<span style="COLOR: #000000">2</span>
				<span style="COLOR: #000000">)<br />test.add(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">a</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">)<br /></span>
		</div>
		<p>可以看到add总是返回一个array，与期望结果一致。</p>
		<p>使用gdc是因为dmd在linux上无法生成共享库。</p>
		<p>在Windows上的编译命令如下：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">dmd </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">oftest.dll test.d test.def ruby18.lib os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">dll.d os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">library.d</span>
		</div>
		<p>ruby18.lib是使用implib从msvcrt-ruby18.dll导出的，这个编译过程很顺利，不过不幸的是它运行有一些问题，大概是一些初始值错误，我暂时还没有找到原因。或许也应该尝试一下gdc，不过我不知道如何从.DLL文件导出一个gdc支持的ELF格式的导入库文件。<br /></p>
		<p>
				<strong>四、项目打算</strong>
		</p>
		<p>打算建立一个rubyd项目，除了转换ruby头文件以外，还要作一些扩展，比如转换D类到ruby类，这方面已有借鉴，比如dsource.org上的pyd项目。</p>
		<p>由于以前在建立项目方面有过失败经历(asgard项目由于兴趣转移和其它原因比如语法丑陋等而未能进行)，这次还是保守一些，先完成D声明的转换，我已经使用工具转换了所有头文件，不过正如前面所说，宏函数和宏常量都丢失了，所以需要重新手工转换。<br /></p>
		<p>
				<strong>五、其它问题</strong>
		</p>
		<p>1、如何从.DLL文件导出一个gdc支持的ELF格式的导入库文件？<strong>如果你知道可以告诉我</strong>，先谢过了。</p>
		<p>2、dmd生成可执行文件问题不大，生成动态链接库或共享库有很大缺陷，特别是不能生成共享库，我可不想再找一个只能再Windows上正常运行的编译器。如何让它改进这些方面？</p>
		<p>3、gdc使用dmd前端和gcc后端，应该会成熟一些，不过一般会比dmd前端版本稍低，而且gdc发布版本不是很频繁，大概4-5个dmd版本才会有一个gdc版本(初略计算)，所以一些新特性不能够及时加入进来。</p><img src ="http://www.cppblog.com/cpunion/aggbug/11427.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-08-19 06:17 <a href="http://www.cppblog.com/cpunion/archive/2006/08/19/11427.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>COM接口IDL转换为D接口以及__uuidof实现。</title><link>http://www.cppblog.com/cpunion/archive/2006/04/11/5283.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Tue, 11 Apr 2006 06:26:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/04/11/5283.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/5283.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/04/11/5283.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/5283.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/5283.html</trackback:ping><description><![CDATA[D语言里面，可以通过version(Windows)来兼容COM接口，不过对于__uuidof却没有相应实现。<br /><br />原始COM接口定义类似这样（找个简单的）：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">[<br />    local,<br />    </span><span style="COLOR: #0000ff">object</span><span style="COLOR: #000000">,<br />    uuid(594f31d0</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">7f19</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">11d0</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">b194</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">00a0c90dc8bf)<br />]<br /></span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000"> IRpcChannelBuffer2 : IRpcChannelBuffer<br />{<br /><br />    HRESULT GetProtocolVersion<br />    (<br />        [</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">out</span><span style="COLOR: #000000">] DWORD </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pdwVersion<br />    );<br />}</span></div><br />VC＋＋中可通过__uuidof操作符来获取COM接口中的uuid“元”信息。<br /><br />转换为D接口后代码如下：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">version(Windows) {<br /><br /></span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000"> IRpcChannelBuffer2 : IRpcChannelBuffer<br />{<br />    HRESULT GetProtocolVersion (DWORD</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> pdwVersion);<br />}<br /><br />}</span></div><br />失去了uuid信息。只要稍作修改，在转换时保存uuid，即可以模板来模拟实现__uuidof操作符。<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">import std.c.windows.com;<br />import std.</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">;<br />import std.stdio;<br /><br /></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br /><br />template HexStrToUbyte(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] str)<br />{<br />    </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexStrToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> cast(ubyte)HexStrToUlong</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str);<br />}<br /><br />template HexStrToUshort(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] str)<br />{<br />    </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">ushort</span><span style="COLOR: #000000"> HexStrToUshort </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> cast(</span><span style="COLOR: #0000ff">ushort</span><span style="COLOR: #000000">)HexStrToUlong</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str);<br />}<br /><br />template HexStrToUint(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] str)<br />{<br />    </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">uint</span><span style="COLOR: #000000"> HexStrToUint </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> cast(</span><span style="COLOR: #0000ff">uint</span><span style="COLOR: #000000">)HexStrToUlong</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str);<br />}<br /><br />template HexStrToUlong(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] str)<br />{<br />    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (str.length </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">ulong</span><span style="COLOR: #000000"> HexStrToUlong </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> HexToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]);<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">ulong</span><span style="COLOR: #000000"> HexStrToUlong <br />            </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> HexToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[length</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">..length]) <br />              </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">16UL</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> HexStrToUlong</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">..length</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]);<br />}<br /><br /></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br /><br />template HexToUbyte(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] c)<br />{<br />    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">A</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xa</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">B</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">b</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xb</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">C</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">c</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xc</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">D</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">d</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xd</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">E</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">e</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xe</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">F</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">f</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xf</span><span style="COLOR: #000000">;<br />}<br /><br />template HexToUbyte_bug(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> c)<br />{<br />    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">A</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xa</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">B</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">b</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xb</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">C</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">c</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xc</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">D</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">d</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xd</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">E</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">e</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xe</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">F</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">f</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xf</span><span style="COLOR: #000000">;<br />}<br /><br />template IIDFromStr(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] str)<br />{<br />    </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> IID IIDFromStr </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {<br />        HexStrToUint</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">]),<br />        HexStrToUshort</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">13</span><span style="COLOR: #000000">]), <br />        HexStrToUshort</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">14</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">18</span><span style="COLOR: #000000">]),<br />        [<br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">19</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">21</span><span style="COLOR: #000000">]),<br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">21</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">23</span><span style="COLOR: #000000">]), <br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">24</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">26</span><span style="COLOR: #000000">]),<br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">26</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">28</span><span style="COLOR: #000000">]), <br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">28</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">30</span><span style="COLOR: #000000">]),<br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">30</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">]), <br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">34</span><span style="COLOR: #000000">]),<br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">34</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">36</span><span style="COLOR: #000000">])<br />        ]<br />    };<br />}<br /><br />template __uuidof(T:IUnknown)<br />{<br />    IID __uuidof </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> IIDFromStr</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">00000000-0000-0000-C000-000000000046</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />}<br /><br />template __uuidof(T:IClassFactory)<br />{<br />    IID __uuidof </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> IIDFromStr</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><span style="COLOR: #000000">00000001-0000-0000-C000-000000000046</span></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />}<br /><br /><br /></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> main()<br />{<br />    IID iu  </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> __uuidof</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(IUnknown);<br />    IID icp </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> __uuidof</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(IClassFactory);<br /><br />    writefln(iu.Data1);<br />    writefln(iu.Data2);<br />    writefln(iu.Data3);<br />    writefln(iu.Data4);<br />}</span></div><br />如上面代码，接口在转换时，把：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><p><span style="COLOR: #000000">[<br />    local,<br />    </span><span style="COLOR: #0000ff">object</span><span style="COLOR: #000000">,<br />    uuid(594f31d0</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">7f19</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">11d0</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">b194</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">00a0c90dc8bf)<br />]<br />interface IRpcChannelBuffer2 : IRpcChannelBuffer<br />{</span></p><p><span style="COLOR: #000000">    HRESULT GetProtocolVersion<br />    (<br />        [in,out] DWORD *pdwVersion<br />    );<br />}</span></p></div><br />转换为：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">template __uuidof(T:IRpcChannelBuffer2)<br />{<br />    IID __uuidof </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> IIDFromStr</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">594f31d0-7f19-11d0-b194-00a0c90dc8bf</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />}<br />version (Windows) {<br /><br /></span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000"> IRpcChannelBuffer2 : IRpcChannelBuffer {<br />    HRESULT GetProtocolVersion (DWORD</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> pdwVersion);<br />}<br /><br />}</span></div><br />即可，这个可以交由自动化工具完成。<br /><br />由于__uuidof模板值在编译期决议，没有实际的运行期开销。<img src ="http://www.cppblog.com/cpunion/aggbug/5283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-04-11 14:26 <a href="http://www.cppblog.com/cpunion/archive/2006/04/11/5283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/D/python性能一比</title><link>http://www.cppblog.com/cpunion/archive/2006/03/31/4840.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 31 Mar 2006 03:06:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/03/31/4840.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/4840.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/03/31/4840.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/4840.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/4840.html</trackback:ping><description><![CDATA[实际上不是全面测试性能。应该这么说：使用一个你熟悉的语言，用它写出一个高效的版本（做下面那件事）。<br /><br />不小心读到一个帖子：http://blog.vckbase.com/jzhang/archive/2006/03/28/18807.html<br /><br />看到C＋＋竟然被比下去了，自然不是很舒服，毕竟C＋＋对于C并没有太大的性能上的降低，而python是C写的（指Cpython实现），自然不会高过C。（废话，C基本上接近汇编效率了）<br /><br />可惜C＋＋又很难找出这么高效的实现，STL效率还是低了些（为什么？一直以为它很高效，用得比较放心）。最近一直比较关注D语言，于是用D语言来测试一下。代码如下：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);">import std.stdio;<br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">import std.</span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);">import std.perf;<br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[][] argv)<br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">{<br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (argv.length </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">) {<br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">    writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Wrong arguments</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">  }<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> READ_SIZE </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1024</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);">  FILE</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> fin </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> fopen(argv[</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">], </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">r</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);">  FILE</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> fout </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> fopen(argv[</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">], </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">w</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> buffer[READ_SIZE];<br /></span><span style="color: rgb(0, 128, 128);">17</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[]] emails;<br /></span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">19</span> <span style="color: rgb(0, 0, 0);">  PerformanceCounter counter </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> PerformanceCounter();<br /></span><span style="color: rgb(0, 128, 128);">20</span> <span style="color: rgb(0, 0, 0);">  counter.start();<br /></span><span style="color: rgb(0, 128, 128);">21</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">feof(fin)){<br /></span><span style="color: rgb(0, 128, 128);">22</span> <span style="color: rgb(0, 0, 0);">    fgets(cast(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)buffer, READ_SIZE, fin);<br /></span><span style="color: rgb(0, 128, 128);">23</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[] email </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> toString(cast(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)buffer);<br /></span><span style="color: rgb(0, 128, 128);">24</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">(email </span><span style="color: rgb(0, 0, 255);">in</span><span style="color: rgb(0, 0, 0);"> emails)){<br /></span><span style="color: rgb(0, 128, 128);">25</span> <span style="color: rgb(0, 0, 0);">      emails[toString(buffer)] </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">26</span> <span style="color: rgb(0, 0, 0);">      fputs(cast(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)email, fout);<br /></span><span style="color: rgb(0, 128, 128);">27</span> <span style="color: rgb(0, 0, 0);">    }<br /></span><span style="color: rgb(0, 128, 128);">28</span> <span style="color: rgb(0, 0, 0);">  }<br /></span><span style="color: rgb(0, 128, 128);">29</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">30</span> <span style="color: rgb(0, 0, 0);">  fclose(fout);<br /></span><span style="color: rgb(0, 128, 128);">31</span> <span style="color: rgb(0, 0, 0);">  fclose(fin);<br /></span><span style="color: rgb(0, 128, 128);">32</span> <span style="color: rgb(0, 0, 0);">  counter.stop();<br /></span><span style="color: rgb(0, 128, 128);">33</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">34</span> <span style="color: rgb(0, 0, 0);">  writefln(counter.milliseconds());<br /></span><span style="color: rgb(0, 128, 128);">35</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">36</span> <span style="color: rgb(0, 0, 0);">}<br /></span><span style="color: rgb(0, 128, 128);">37</span> <span style="color: rgb(0, 0, 0);"></span></div><br />没加fopen失败处理。<br /><br />测试结果在我的机器上耗时只有python版本的1/3，我看到其它网友