??xml version="1.0" encoding="utf-8" standalone="yes"?>色青青草原桃花久久综合,久久国产精品99精品国产,99久久这里只有精品 http://m.shnenglu.com/cpunion/category/320.htmlAS/C/C++/D/Java/JS/Python/Ruby zh-cn Mon, 19 May 2008 13:00:17 GMT Mon, 19 May 2008 13:00:17 GMT 60 [D语言] D语言数组 http://m.shnenglu.com/cpunion/archive/2006/10/07/13418.htmlqiezi qiezi Sat, 07 Oct 2006 08:21:00 GMT http://m.shnenglu.com/cpunion/archive/2006/10/07/13418.html http://m.shnenglu.com/cpunion/comments/13418.html http://m.shnenglu.com/cpunion/archive/2006/10/07/13418.html#Feedback 4 http://m.shnenglu.com/cpunion/comments/commentRss/13418.html http://m.shnenglu.com/cpunion/services/trackbacks/13418.html void main(){ int [] c = [ 1 , 2 , 3 ]; foreach (inout int i; c){ writef( & i); writef( " , " ); } writefln( "" ); c.length = 2 ; foreach (inout int i; c){ writef( & i); writef( " , " ); } writefln( "" ); c.length = 3 ; foreach (inout int i; c){ writef( & i); writef( " , " ); } writefln( "" ); c.length = 4 ; foreach (inout int i; c){ writef( & i); writef( " , " ); } writefln( "" ); }
它输出结果如下: B7D19FB0, B7D19FB4, B7D19FB8, B7D19FB0, B7D19FB4, B7D19FB0, B7D19FB4, B7D19FB8, B7D1CFA0, B7D1CFA4, B7D1CFA8, B7D1CFAC, 可以看到?行地址相同Q后面一行地址不同。ؓ什么? D语言的数l分配是内存紧凑的,当减数l长度减时Q只需要修改切片大而不需要重新分配。当长度变大Ӟ也会查原来的~冲区是否够大,以确定是否需要重新分配空间。注意第2ơ操作时把长度恢复ؓ原来大小Ӟq真的恢复了原来的状态,后面长出来的元素会被初始化ؓ默认倹{?br /> 再来看一个:void main(){ int [] c = [ 1 , 2 , 3 ]; int [] d = c; foreach (inout int i; c){ writef( & i); writef( " , " ); } writefln( "" ); foreach (inout int i; d){ writef( & i); writef( " , " ); } writefln( "" ); d.length = 2 ; foreach (inout int i; c){ writef( & i); writef( " , " ); } writefln( "" ); foreach (inout int i; d){ writef( & i); writef( " , " ); } writefln( "" ); d.length = 4 ; foreach (inout int i; c){ writef( & i); writef( " , " ); } writefln( "" ); foreach (inout int i; d){ writef( & i); writef( " , " ); } writefln( "" ); }
在执行int[] d = c;以后Qd的确是和c׃n了存储区。不q在改变d的长度以后,它就和c分道扬镳了。所以int[] d = c不能理解为d是一个指向c的引用,它实际上创徏了一个新的数l对象,但ƈ不拷贝数l元素,它和int[] d = c[0 .. length]是等LQ都是数l切片操作?br /> q个问题让我困惑不已。比如你用char[]表示一个单词,用char[][]表示一行,char[][][]表示多行。如何引用这个单词?你当然可以每ơ用lines[i][j]Q但如果处理步骤很多Q这会不会看h很头大? 看上d该这样用:char [][][] lines; char [][] line = lines[ 0 ]; line.length = line.length + 1 ; line[length - 1 ] = " , " ;
可惜Ҏ前面的结论,q将无法影响到lines。如果找不到一个引用类型指向数l,有时候用v来还真是很麻烦。看h把Line/Word包装成类是个勉强凑合的主意。。?img src ="http://m.shnenglu.com/cpunion/aggbug/13418.html" width = "1" height = "1" /> ]]>[D语言] Array slicing http://m.shnenglu.com/cpunion/archive/2006/10/06/13393.htmlqiezi qiezi Fri, 06 Oct 2006 01:35:00 GMT http://m.shnenglu.com/cpunion/archive/2006/10/06/13393.html http://m.shnenglu.com/cpunion/comments/13393.html http://m.shnenglu.com/cpunion/archive/2006/10/06/13393.html#Feedback 0 http://m.shnenglu.com/cpunion/comments/commentRss/13393.html http://m.shnenglu.com/cpunion/services/trackbacks/13393.html 指针的slicing操作和数lslicing语意是相同的?br /> 通过slicing生成D数组Q比原来直接使用指针的好处是可以有边界检查?br /> 最q刚好犯了这个错误,在用freetypeӞrender出来的位图数据直接用slicing生成数组保存h。由于slicingq不复制数据Q这样后面的render操作会覆盖前面的数据Q所以我保存的数l其实都指向同一个缓冲区。当释放face对象Ӟ~冲Z没了Q再讉K恐怕要D错误了?br /> q个是D文档中明描qC的,我却׃Ҏ间才排除q个错误Q写下来记录之~ ]]>[D语言] DMD 0.168发布 http://m.shnenglu.com/cpunion/archive/2006/10/05/13362.htmlqiezi qiezi Thu, 05 Oct 2006 01:23:00 GMT http://m.shnenglu.com/cpunion/archive/2006/10/05/13362.html http://m.shnenglu.com/cpunion/comments/13362.html http://m.shnenglu.com/cpunion/archive/2006/10/05/13362.html#Feedback 5 http://m.shnenglu.com/cpunion/comments/commentRss/13362.html http://m.shnenglu.com/cpunion/services/trackbacks/13362.html 1、给委托增加ptr属性,指向委托所l定的对象?br />q是一个语法糖Qdg.ptr被{化ؓcast(void*)dgQ它只能作右|所以除了能d它以外,在语法上止对它赋倹{要x委托l定C同的对象Q你只能自己实现Q?br />class Foo{ int foo; public : this ( int foo){ this .foo = foo; } void bar(){ writefln(foo); } } void main(){ alias void delegate () DG; DG dg = & ( new Foo( 1 )).bar; Foo[ 10 ] foos; foreach ( int i, inout Foo foo; foos){ foo = new Foo(i); } void ** ptr = cast( void ** ) & dg; foreach (Foo foo; foos){ * ptr = cast( void * )foo; dg(); } }
q种方式也不是我们所希望的,一般来说委托绑定到多个对象Ӟ因ؓ是取到某成员函数指针Q再q行l定。比如模拟一个ActiveSupport所扩展的一个ruby.Array#map用法Q?br />import std.stdio; class Foo{ int foo; public : this ( int foo){ this .foo = foo; } void bar(){ writefln(foo); } } class Array(T){ private : T[] data; public : this (T[] data){ this .data = data[ 0 .. length]; } void map( void function() func){ void delegate () dg; void ** funcPtr = cast( void ** ) & dg + 1 ; * funcPtr = func; void ** ptr = cast( void ** ) & dg; foreach (T v; data){ * ptr = cast( void * )v; dg(); } } } void main(){ auto arr = new Array ! (Foo)([ new Foo( 1 ), new Foo( 2 ), new Foo( 3 )]); arr.map( & Foo.bar); }
是的Qdelegate内部保存?个指针,所以我们可以容易地hack它?br /> [注:上面的main函数中数l直接量赋给栈对象也是这个版本中新增的内容,昄只能用于static对象是很鸡肋的。这里简单带q不提。] [注:上面q个map的模拟ƈ不是ActiveSupport的map扩展的全部用途,那个mapq是攉q回|q里只演C用语法。ActiveSupport中扩展的map调用语法是map(&:to_s)Q就可以攉到数l中所有元素调用to_s后的q回倹{] 2、给内嵌内的实例增加outer属性,指向外层对象?br />import std.stdio; class Outer{ class Inner{} this (){ Inner inner = new Inner; inner.outer.foo(); } void foo(){ writefln( " foo " ); } } void main(){ Outer outer = new Outer; }
q个Ҏ可能应用ƈ不是很广吧?br /> 3、mixin多个析构函数?br />template A(){ this (){ } ~ this (){ writefln( " A::~A() " ); } } template B(){ ~ this (){ writefln( " B::~B() " ); } } class C{ mixin A; mixin B; } void main(){ C c = new C; delete c; }
q些析构函数会和mixin相反的顺序执行。我不明白的是,Z么不让mixin多个构造函敎ͼZ不让q些构造函数晚于被mixin的类Q上面的Cc)的构造函敎ͼq按mixinq来的顺序执行? ]]> [D语言] DMD 0.167发布 http://m.shnenglu.com/cpunion/archive/2006/09/19/12721.htmlqiezi qiezi Tue, 19 Sep 2006 12:16:00 GMT http://m.shnenglu.com/cpunion/archive/2006/09/19/12721.html http://m.shnenglu.com/cpunion/comments/12721.html http://m.shnenglu.com/cpunion/archive/2006/09/19/12721.html#Feedback 2 http://m.shnenglu.com/cpunion/comments/commentRss/12721.html http://m.shnenglu.com/cpunion/services/trackbacks/12721.html import std . stdio; void main(){ { static int [] arr = [ 1 , 2 , 3 , 4 , 5 ]; writefln(typeid(typeof(arr[ 0 ]))); writefln(arr); } { static float[] arr = [1f , 1 , 3 , 4 , 5 ]; writefln(typeid(typeof(arr[ 0 ]))); writefln(arr); } { static char[][] arr = [ " 1 " , " 2 " , " 3 " , " 4 " , " 5 " ]; writefln(typeid(typeof(arr[ 0 ]))); writefln(arr); } }
数组cdq1个元素类型决定,cd不匹配将会生编译错误?br /> 接着是多l数l:import std . stdio; void main(){ static int [][] arr = [[ 1 , 2 , 3 , 4 ] , [ 4 , 5 , 6 ] , [ 7 , 8 ]]; foreach ( int [] sub ; arr){ foreach ( int i; sub ){ writefln(i); } } }
另一个特性是更强的typedef。原有的typedef强类型在某些情况下会产生混ؕ?br /> 下面的代码摘?http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D.bugs&artnum=3843import std . stdio; typedef int Int1; typedef int Int2; void show(Int1 v) { writefln( " Int1: %d " , v); } void show(Int2 v) { writefln( " Int2: %d " , v); } void show( int i) { writefln( " int: %d " , i); } void show(long l) { writefln( " long: %d " , l); } void main() { Int1 value1 = 42 ; Int2 value2 = 69 ; show(value1 + value2); show(value2 + value1); show( 2 * value1); show(value1 * 2 ); show(value1 + value1); show(value2 - value2); show(value1 + 2 ); show( 3 + value2); long l = 23 ; show(value1 + l); show(l + value2); short s = 105 ; show(s + value1); show(value2 + s); }
如上面代码所C。typedef定义出来的类型和原有cd的相同Ş式重载函数可以共存,q可以完成更强类型的重蝲QCQ+的重载还不能实现q个?br /> q个强类型的typedef好像原本支持,大概是运结果类型比较模p?br /> 好处是显|见的。比如有一个Time和TimeIntervalcdQ它用来表示l对旉或相Ҏ间间隔;另有一个输出函数用来显C结果?br />import std . stdio; import std . string; typedef long Time ; typedef long TimeInterval; void output( Time t){ writefln( " Time: " ~ toString(cast(long)t)); } void output(TimeInterval t){ writefln( " Interval: " ~ toString(cast(long)t)); } void main(){ Time time = cast( Time ) 100 ; TimeInterval interval = cast(TimeInterval) 100 ; output( time ); output(interval); }
是的Q用上ȝ了很多,因ؓ我们试图用一个数值类型去表示多个矢量cd?br /> q里Time time = cast(Time)100不再只是100q个单的数|它还携带了Timeq个cd。TimeInterval interval = cast(TimeInterval)100也不只是100q个数|我们l它赋予了时间间隔的含义?br /> q可以想像得更开阔一些,用它定义旉、长度、面U、加速度、速度、温度等Q重载一些计函敎ͼ可惜Dq不支持全局操作W重载)Q这样就方便完成一些物理量的运了Q而且cd得到查,速度加一个整数值结果还是速度Q速度乘时间得到的是长度,旉减时间得到的是时间间隔,速度加时间将产生~译错误。。。。。。神奇的是这些类型可能都是一些简单类型,我相信它臛_可以保证q行效率不会太低。当然你用CQ+cM可以完成q些Qƈ且利用编译器优化让它的效率保持最高,甚至内联的结果就是简单类型的q算Q我q是更愿意用这单的cd来typedef。当然这可能需要写大量重复的函数重载Ş式,没有关系Q我想用模板和mixin应该可以化这一q程Q而且会有相当多的家伙们愿意用这U麻烦的形式来获得更“正”的~译查?br /> 所以说QD语言的typedef的意义其实就是实C矢量cd?br /> 又多想了一炏V?br /> 强类型要Q语法糖也应该要。是不是可以借鉴一下ruby的语法,实现q种调用呢?Length l = 1 . cm; l = 1 . m; Time t = Time . now; TimeInterval i = 3 . hours;
免去了一些初始化的麻烦?br /> ]]>[D语言] DMD 0.166发布 http://m.shnenglu.com/cpunion/archive/2006/09/01/11938.htmlqiezi qiezi Fri, 01 Sep 2006 14:34:00 GMT http://m.shnenglu.com/cpunion/archive/2006/09/01/11938.html http://m.shnenglu.com/cpunion/comments/11938.html http://m.shnenglu.com/cpunion/archive/2006/09/01/11938.html#Feedback 10 http://m.shnenglu.com/cpunion/comments/commentRss/11938.html http://m.shnenglu.com/cpunion/services/trackbacks/11938.html 取消的理由是q个转换太隐晦了Q最好是昑ּ地标C出q种转换Q所以引入一个lazy关键字。D语言q在发展中,很多Ҏ都在尝试,q种修改也不是第一ơ了?br /> 首先看看q个lazy?br /> 上一版实Cq样一个特性:void log( char [] delegate () msg){ writefln(msg()); } log( " Hello, " ~ " Li Jie! \n " ~ " Welcome! " );
log的参数被隐式转化Z个委托,q样只有用到q个值的时候才真正求倹{?br /> ׃q种隐式转化很容易Ş成陷阱,所以这一版改Z个lazy关键字,看v来要z一些了Q?br />void log(lazy char [] msg){ writefln(msg); } log( " Hello, " ~ " Li Jie! \n " ~ " Welcome! " );
log函数中用msgq个变量׃调用那个隐式的委托,要注意的是每ơ取msg的值都会执行这个委托,所以我觉得q个陷阱更大了,当然它把陷阱丢给~写代码的hQ而不是用代码的人,所以好坏还无从分L?br /> 下面q点代码可以演示q个陷阱:void foo(lazy int a){ int b = a + 1 ; int c = a * 3 ; int d = a / 2 ; } int bar(){ writefln( " Call bar() " ); return 12 ; } foo(bar());
看v来bar好像会执行一ơ,实际上这D代码会打印??Call bar()"Q原来用委托还可以看到一个显式的函数调用呢?br /> 另一个member templatesҎ未见到文Q猜惛_概是支持成员函数模板吧?br /> ]]>[D语言] DMD 0.165发布 http://m.shnenglu.com/cpunion/archive/2006/08/21/11517.htmlqiezi qiezi Mon, 21 Aug 2006 05:24:00 GMT http://m.shnenglu.com/cpunion/archive/2006/08/21/11517.html http://m.shnenglu.com/cpunion/comments/11517.html http://m.shnenglu.com/cpunion/archive/2006/08/21/11517.html#Feedback 2 http://m.shnenglu.com/cpunion/comments/commentRss/11517.html http://m.shnenglu.com/cpunion/services/trackbacks/11517.html 详细信息可见Q?a >http://www.digitalmars.com/d/lazy-evaluation.html 它首先解决了一个存在于java中的日志问题Qjava里面一个写日志标准格式如下Q?br />if (log.isLoggable(Level.INFO)) { log.info( " aaaa " ); }
因ؓlog.info的参数求值可能媄响性能Q所以用这U繁琐的方式来降低关闭日志时的性能开销?br /> C/C++使用宏来解决q个问题Q唯一的问题是修改日志U别会导致项目必重~译?br /> [注:指的是用宏来定义日志U别的方式,使用其它动态修Ҏ志别的方式Ҏ能要求很高的项目来说可能不可接受] D语言使用另一U方式来解决Q首先要用到“表辑ּ到委托的隐式转换”,下面是委托作为参数时的用方法:void foo( char [] delegate () dg){ writefln(dg()); } foo( delegate char [] (){ return " Hello, World " ; } );
因ؓq个委托q不需要参敎ͼ而返回值可以推|所以在早先的一个版本里QD允许我们化这个过E:void foo( char [] delegate () dg){ writefln(dg()); } foo({ return " Hello, World " ;});
DMD 0.165允许我们更进一步:void foo( char [] delegate () dg){ writefln(dg()); } foo( " Hello, World " );
q个字符串参C被隐式{换成一个委托?br /> 现在可以用一LҎ处理日志Q在没有宏的pȝ中,日志函数一般格式如下:void log( char [] message) { if (logging) fwritefln(logfile, message); }
Z让它使用懒惰求D个特性,q里把这个函数的参数改ؓ委托Q?br />void log( char [] delegate () dg) { if (logging) fwritefln(logfile, dg()); }
从上面提到的内容我们知道使用它也很简单:log( " My name is " ~ " Li Jie " ); q个参数的求值就是在log函数里面完成的?br /> 当然委托会增加一些开销Q在上面q个例子中,q个开销是在日志打开时执行委托所带来的,它增加了一ơ委托调用的开销Q不q好在打开日志功能Ӟ其它斚w的开销q大q委托调用。关闭日志时Q它不会带来开销Q它只是把字W串指针压栈改ؓ委托指针压栈?img src ="http://m.shnenglu.com/cpunion/aggbug/11517.html" width = "1" height = "1" /> ]]>[D语言] 用D语言~写Ruby扩展 http://m.shnenglu.com/cpunion/archive/2006/08/19/11427.htmlqiezi qiezi Fri, 18 Aug 2006 22:17:00 GMT http://m.shnenglu.com/cpunion/archive/2006/08/19/11427.html http://m.shnenglu.com/cpunion/comments/11427.html http://m.shnenglu.com/cpunion/archive/2006/08/19/11427.html#Feedback 11 http://m.shnenglu.com/cpunion/comments/commentRss/11427.html http://m.shnenglu.com/cpunion/services/trackbacks/11427.html Ruby语言的官方解释程序是使用C语言开发的Q一般用C语言来编写扩展。D语言和C语言是二q制兼容的,所以可以用D语言~写Ruby扩展?br />
一、移植C库到D的一般过E?/strong>
C使用头文件来处理W号依赖Q在D里面链接外部库文件时Q要使用extern (C)声明来引入符Pq是一个{换过E?/p>
如何转换一个C头文件到D文gQD文档的htomodule.html有详说明。一般的转换q程如下Q?
1、运行预处理E序处理掉头文g里面的宏?/p>
2、删除经q预处理以后的多余信息。由于C的头文g包含Q每个头文gl过预处理以后都会包含一些重复内容,我们需要剔除这部分内容Q通过查找行号卛_完成?/p>
3、{换相应声明到D声明Q这一步可以用一个c2hE序来完成?/p>
注意预处理程序处理完毕以后,宏函C及宏定义的常量会被去除,q可能不是你惌的,所以最好的办法可能是手工{换?/p>
另一U调用是在D里面调用动态链接库Q这需要你使用implib工具从动态链接库产生一?lib导入库文Ӟ然后生成D声明Q再~译链接卛_。如果是在linux下用共享库Q则只需要编写D声明文gQ然后直接链接即可?br />
二、调用C?/strong>
转换完毕以后Q就可以调用了。如果你只是要测试一下,可以只声明使用q的外部函数、变量即可?/p>
例如我们要编写Programming Ruby里面的一个Ruby Extension例子Q相应的D代码如下Q?/p>
//
test.d
module test; import ruby;
extern
(C) VALUE t_init(VALUE self) { VALUE arr
=
rb_ary_new(); rb_iv_set(self,
"
@arr
"
, arr);
return
self; }
extern
(C) VALUE t_add(VALUE self, VALUE anObject) { VALUE arr
=
rb_iv_get(self,
"
@arr
"
); rb_ary_push(arr, anObject);
return
arr; }
extern
(C){ VALUE cTest; alias VALUE(
*
func_type)(); export
void
Init_Test() { cTest
=
rb_define_class(
"
Test
"
, rb_cObject); rb_define_method(cTest,
"
initialize
"
, cast(func_type)
&
t_init,
0
); rb_define_method(cTest,
"
add
"
, cast(func_type)
&
t_add,
1
); } }
//
extern(C)
和C代码很相伹{由于我们只使用了几个外部函数、变量,所以只需要声明这几个W号卛_Q?/p>
//
ruby.d
module ruby;
extern
(C){ alias
ulong
VALUE; VALUE rb_cObject; VALUE rb_ary_new (); VALUE rb_ary_push (VALUE, VALUE); VALUE rb_iv_set (VALUE,
char
*
, VALUE); VALUE rb_iv_get (VALUE,
char
*
); VALUE rb_define_class (
char
*
,VALUE);
void
rb_define_method (VALUE,
char
*
,VALUE(
*
)(),
int
); }
三、生成动态链接库(Windows DLL)或共享库(Linux so文g)
D语言在Windows上编写DLLQ除了要有D源文件以外,q要有DLL定义文gQ?/p>
//
test.def
LIBRARY Test DESCRIPTION
'
Test written in D
'
EXETYPE NT CODE PRELOAD DISCARDABLE DATA PRELOAD SINGLE
q是一个通用的格式,只是一些描qC息,因ؓD中可以用export关键字导出符P所以不需要在q里声明导出函数Q只有在~写COM DLL时才会增加其它一些信息?/p>
另外׃D语言要初始化GC以及其它一些信息,所以还需要在DllMain里面调用初始化及l止代码。由于不同^台的初始化过E不完全相同Q这里我单封闭了一下不同^台的初始化代码:
//
os/library.d
module os.library;
extern
(C){
void
gc_init();
void
gc_term(); version(Windows)
void
_minit();
void
_moduleCtor();
void
_moduleDtor();
void
_moduleUnitTests(); version(linux)
void
_STI_monitor_staticctor(); version(linux)
void
_STI_critical_init(); version(linux)
void
_STD_monitor_staticdtor(); version(linux)
void
_STD_critical_term(); }
extern
(C)
void
d_init() {
//
writefln("Start init D runtime");
version(linux) _STI_monitor_staticctor(); version(linux) _STI_critical_init(); gc_init(); version(Windows) _minit(); _moduleCtor(); _moduleUnitTests();
//
writefln("init finished");
}
extern
(C)
void
d_fini() {
//
writefln("Start term D runtime");
_moduleDtor(); gc_term(); version(linux) _STD_critical_term(); version(linux) _STD_monitor_staticdtor();
//
writefln("term finished");
}
现在可以为Windows~写初始化及l止代码Q?/p>
//
os/dll.d
module os.dll;
private
import os.library;
private
import std.c.windows.windows; HINSTANCE g_hInst;
extern
(Windows) BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved) {
switch
(ulReason) {
case
DLL_PROCESS_ATTACH: d_init();
break
;
case
DLL_PROCESS_DETACH: d_fini();
break
;
case
DLL_THREAD_ATTACH:
case
DLL_THREAD_DETACH:
//
Multiple threads not supported yet
return
false
; } g_hInst
=
hInstance;
return
true
; }
׃Linux׃n库ƈ没有标准的入口函?或是我不知道?Q这里用gcc扩展的初始、终止代码,不过是以C语言实现的:
//
os/so.c
#include
<
ruby.h
>
static
void
so_init(
void
) __attribute__((constructor));
static
void
so_fini(
void
) __attribute__((destructor));
extern
void
d_init(
void
);
extern
void
d_fini(
void
);
void
so_init(
void
) { d_init(); }
void
so_fini(
void
) { d_fini(); }
现在可以试~译链接Q在Linux上编译命令如下:
gcc
-
o os
/
so.o
-
c os
/
so.c
-
I
/
usr
/
lib
/
ruby
/
1.8
/
i686
-
linux gdc
-
o Test.so test.d os
/
so.o ruby.d
-
shared
-
fPIC
-
lruby
你可以在irb下测试:
require
'
Test
'
test
=
Test.
new
test.add(
1
) test.add(
2
) test.add(
"
a
"
)
可以看到addLq回一个arrayQ与期望l果一致?/p>
使用gdc是因为dmd在linux上无法生成共享库?/p>
在Windows上的~译命o如下Q?/p>
dmd
-
oftest.dll test.d test.def ruby18.lib os
/
dll.d os
/
library.d
ruby18.lib是用implib从msvcrt-ruby18.dll导出的,q个~译q程很顺利,不过不幸的是它运行有一些问题,大概是一些初始值错误,我暂时还没有扑ֈ原因。或怹应该试一下gdcQ不q我不知道如何从.DLL文g导出一个gdc支持的ELF格式的导入库文g?br />
四、项目打?/strong>
打算建立一个rubyd目Q除了{换ruby头文件以外,q要作一些扩展,比如转换Dcdrubyc,q方面已有借鉴Q比如dsource.org上的pyd目?/p>
׃以前在徏立项目方面有q失败经?asgard目׃兴趣转移和其它原因比如语法丑陋等而未能进?Q这ơ还是保守一些,先完成D声明的{换,我已l用工兯{换了所有头文gQ不q正如前面所_宏函数和宏常量都丢失了,所以需要重新手工{换?br />
五、其它问?/strong>
1、如何从.DLL文g导出一个gdc支持的ELF格式的导入库文gQ?strong>如果你知道可以告诉我Q先谢过了?/p>
2、dmd生成可执行文仉题不大,生成动态链接库或共享库有很大缺P特别是不能生成共享库Q我可不惛_找一个只能再Windows上正常运行的~译器。如何让它改q这些方面?
3、gdc使用dmd前端和gcc后端Q应该会成熟一些,不过一般会比dmd前端版本E低Q而且gdc发布版本不是很频J,大概4-5个dmd版本才会有一个gdc版本(初略计算)Q所以一些新Ҏ不能够及时加入q来?/p>
]]>COM接口IDL转换为D接口以及__uuidof实现?/title> http://m.shnenglu.com/cpunion/archive/2006/04/11/5283.htmlqiezi qiezi Tue, 11 Apr 2006 06:26:00 GMT http://m.shnenglu.com/cpunion/archive/2006/04/11/5283.html http://m.shnenglu.com/cpunion/comments/5283.html http://m.shnenglu.com/cpunion/archive/2006/04/11/5283.html#Feedback 0 http://m.shnenglu.com/cpunion/comments/commentRss/5283.html http://m.shnenglu.com/cpunion/services/trackbacks/5283.html 原始COM接口定义cMq样Q找个简单的Q:[ local, object , uuid(594f31d0 - 7f19 - 11d0 - b194 - 00a0c90dc8bf) ] interface IRpcChannelBuffer2 : IRpcChannelBuffer { HRESULT GetProtocolVersion ( [ in , out ] DWORD * pdwVersion ); }
VCQ+中可通过__uuidof操作W来获取COM接口中的uuid“元”信息?br /> 转换为D接口后代码如下:version(Windows) { interface IRpcChannelBuffer2 : IRpcChannelBuffer { HRESULT GetProtocolVersion (DWORD * pdwVersion); } }
失去了uuid信息。只要稍作修改,在{换时保存uuidQ即可以模板来模拟实现__uuidof操作W?br />import std.c.windows.com; import std. string ; import std.stdio; private : template HexStrToUbyte( char [] str) { const ubyte HexStrToUbyte = cast(ubyte)HexStrToUlong ! (str); } template HexStrToUshort( char [] str) { const ushort HexStrToUshort = cast( ushort )HexStrToUlong ! (str); } template HexStrToUint( char [] str) { const uint HexStrToUint = cast( uint )HexStrToUlong ! (str); } template HexStrToUlong( char [] str) { static if (str.length == 1 ) const ulong HexStrToUlong = HexToUbyte ! (str[ 0 .. 1 ]); else const ulong HexStrToUlong = HexToUbyte ! (str[length - 1 ..length]) + 16UL * HexStrToUlong ! (str[ 0 ..length - 1 ]); } private : template HexToUbyte( char [] c) { static if (c[ 0 ] >= ' 0 ' && c[ 0 ] <= ' 9 ' ) const ubyte HexToUbyte = c[ 0 ] - ' 0 ' ; else static if (c[ 0 ] == ' A ' || c[ 0 ] == ' a ' ) const ubyte HexToUbyte = 0xa ; else static if (c[ 0 ] == ' B ' || c[ 0 ] == ' b ' ) const ubyte HexToUbyte = 0xb ; else static if (c[ 0 ] == ' C ' || c[ 0 ] == ' c ' ) const ubyte HexToUbyte = 0xc ; else static if (c[ 0 ] == ' D ' || c[ 0 ] == ' d ' ) const ubyte HexToUbyte = 0xd ; else static if (c[ 0 ] == ' E ' || c[ 0 ] == ' e ' ) const ubyte HexToUbyte = 0xe ; else static if (c[ 0 ] == ' F ' || c[ 0 ] == ' f ' ) const ubyte HexToUbyte = 0xf ; } template HexToUbyte_bug( char c) { static if (c >= ' 0 ' && c <= ' 9 ' ) const ubyte HexToUbyte1 = c - ' 0 ' ; else static if (c == ' A ' || c == ' a ' ) const ubyte HexToUbyte1 = 0xa ; else static if (c == ' B ' || c == ' b ' ) const ubyte HexToUbyte1 = 0xb ; else static if (c == ' C ' || c == ' c ' ) const ubyte HexToUbyte1 = 0xc ; else static if (c == ' D ' || c == ' d ' ) const ubyte HexToUbyte1 = 0xd ; else static if (c == ' E ' || c == ' e ' ) const ubyte HexToUbyte1 = 0xe ; else static if (c == ' F ' || c == ' f ' ) const ubyte HexToUbyte1 = 0xf ; } template IIDFromStr( char [] str) { const IID IIDFromStr = { HexStrToUint ! (str[ 0 .. 8 ]), HexStrToUshort ! (str[ 9 .. 13 ]), HexStrToUshort ! (str[ 14 .. 18 ]), [ HexStrToUbyte ! (str[ 19 .. 21 ]), HexStrToUbyte ! (str[ 21 .. 23 ]), HexStrToUbyte ! (str[ 24 .. 26 ]), HexStrToUbyte ! (str[ 26 .. 28 ]), HexStrToUbyte ! (str[ 28 .. 30 ]), HexStrToUbyte ! (str[ 30 .. 32 ]), HexStrToUbyte ! (str[ 32 .. 34 ]), HexStrToUbyte ! (str[ 34 .. 36 ]) ] }; } template __uuidof(T:IUnknown) { IID __uuidof = IIDFromStr ! ( " 00000000-0000-0000-C000-000000000046 " ); } template __uuidof(T:IClassFactory) { IID __uuidof = IIDFromStr ! ( " 00000001-0000-0000-C000-000000000046 " ); } void main() { IID iu = __uuidof ! (IUnknown); IID icp = __uuidof ! (IClassFactory); writefln(iu.Data1); writefln(iu.Data2); writefln(iu.Data3); writefln(iu.Data4); }
如上面代码,接口在{换时Q把Q?br />[ local, object , uuid(594f31d0 - 7f19 - 11d0 - b194 - 00a0c90dc8bf) ] interface IRpcChannelBuffer2 : IRpcChannelBuffer {
HRESULT GetProtocolVersion ( [in,out] DWORD *pdwVersion ); }
转换为:template __uuidof(T:IRpcChannelBuffer2) { IID __uuidof = IIDFromStr ! ( " 594f31d0-7f19-11d0-b194-00a0c90dc8bf " ); } version (Windows) { interface IRpcChannelBuffer2 : IRpcChannelBuffer { HRESULT GetProtocolVersion (DWORD * pdwVersion); } }
卛_Q这个可以交p动化工具完成?br /> ׃__uuidof模板值在~译期决议,没有实际的运行期开销?img src ="http://m.shnenglu.com/cpunion/aggbug/5283.html" width = "1" height = "1" /> ]]> C++/D/python性能一?/title> http://m.shnenglu.com/cpunion/archive/2006/03/31/4840.htmlqiezi qiezi Fri, 31 Mar 2006 03:06:00 GMT http://m.shnenglu.com/cpunion/archive/2006/03/31/4840.html http://m.shnenglu.com/cpunion/comments/4840.html http://m.shnenglu.com/cpunion/archive/2006/03/31/4840.html#Feedback 0 http://m.shnenglu.com/cpunion/comments/commentRss/4840.html http://m.shnenglu.com/cpunion/services/trackbacks/4840.html 不小心读C个帖子:http://blog.vckbase.com/jzhang/archive/2006/03/28/18807.html 看到CQ+竟然被比下去了,自然不是很舒服,毕竟CQ+对于Cq没有太大的性能上的降低Q而python是C写的Q指Cpython实现Q,自然不会高过C。(废话QC基本上接q汇~效率了Q?br /> 可惜CQ+又很难找么高效的实现QSTL效率q是低了些(Z么?一直以为它很高效,用得比较攑ֿQ。最q一直比较关注D语言Q于是用D语言来测试一下。代码如下: 1 import std.stdio; 2 import std. string ; 3 import std.perf; 4 5 int main( char [][] argv) 6 { 7 if (argv.length < 3 ) { 8 writefln( " Wrong arguments " ); 9 return 1 ; 10 } 11 12 const int READ_SIZE = 1024 ; 13 14 FILE * fin = fopen(argv[ 1 ], " r " ); 15 FILE * fout = fopen(argv[ 2 ], " w " ); 16 char buffer[READ_SIZE]; 17 int [ char []] emails; 18 19 PerformanceCounter counter = new PerformanceCounter(); 20 counter.start(); 21 while ( ! feof(fin)){ 22 fgets(cast( char * )buffer, READ_SIZE, fin); 23 char [] email = toString(cast( char * )buffer); 24 if ( ! (email in emails)){ 25 emails[toString(buffer)] = 0 ; 26 fputs(cast( char * )email, fout); 27 } 28 } 29 30 fclose(fout); 31 fclose(fin); 32 counter.stop(); 33 34 writefln(counter.milliseconds()); 35 return 0 ; 36 } 37
没加fopenp|处理?br /> 试l果在我的机器上耗时只有python版本?/3Q我看到其它|友的CQ+实现最好成l也不过1/2Q由于是D是C语言所写,试使用的又是C库,自然可以认ؓC语言q是比较高效的?br /> 上面的D语言代码里调用了toStringQ把char*转ؓchar[]Q它的源代码如下Q?br />char [] toString( char * s) { return s ? s[ 0 .. strlen(s)] : cast( char []) null ; }
如果s[0 .. strlen(s)]产生了复制的话,应该是会影响性能的。char[]对象是受GC理的,应该会复制一份。这U情况下q能有如此高的效率,的确很不错?br /> 不过python的性能让我感觉很吃惊,以前只测试过字符串连接,感觉比较高效?br /> 写了一个完成一样功能的rubyE序Q耗时接近python版本?倍,当然׃对它不是很熟Q可能写得不够高效?br /> 1 emails = Hash. new 2 3 start = Time.now 4 fout = open( ' email-2-new1.txt ' , ' w ' ) 5 open( ' email-2.txt ' ).each do | line | 6 if ! emails.has_key ? line 7 emails[line] = 0 8 fout << line 9 end 10 end 11 puts Time.now - start 12
正如某网友所_q个E序的瓶颈在于IOQ拿来作性能上的比较或许是不合适的。从语言效率上来Ԍ自然是C++和D相当Q可能会比D高,python应该会低很多。但在很多情况下Q衡量效率不光是语言本nQ还有库Q没有库的语a是没什么吸引力的。python是一U很“慢”的语言Q相对C/CQ+来说Q不q它是一门实用性的语言Q所以它Z些特定用法做了优化,取得了不错的成W。CQ+是一门通用语言Q或许太注重语言的性能了,忽略了库Q导致库把性能l拉下来了。这U情况下Q有java和CQ+的性能Q结果是java要高Q自然是不那么让人惊奇的了。可是如果标准库都这么慢Q那q能指望什么呢Q?br /> 当然也ƈ没有证明STLq别慢Q也可能是用不正确?br /> 只是刚好看到q个比较Q忍不住参与一下,切勿当真?br /> ]]> [转] digitalmars.D上的一个徏议?/title> http://m.shnenglu.com/cpunion/archive/2006/03/28/4675.htmlqiezi qiezi Tue, 28 Mar 2006 02:31:00 GMT http://m.shnenglu.com/cpunion/archive/2006/03/28/4675.html http://m.shnenglu.com/cpunion/comments/4675.html http://m.shnenglu.com/cpunion/archive/2006/03/28/4675.html#Feedback 0 http://m.shnenglu.com/cpunion/comments/commentRss/4675.html http://m.shnenglu.com/cpunion/services/trackbacks/4675.html Proposal: Operator overloading without temporaries 作者:Don Clugston <dac@nospam.com.au> 正文Q?br />Background: Operator overloading, in the form it exists in C++ and currently in D, inherently results in sub-optimal code, because it always results in unnecessary temporary objects being created. For example, X = A - ((B*C) + D)* E; becomes: T1 = B * C; T2 = T1 + D; T3 = T2 * E; T4 = A - T3; X = T4; Four objects were created, whereas only one was strictly required. In C++, there are libraries like Blitz++ which use complicated expression templates in order to avoid these creating these temporaries, and provide performance comparable with FORTRAN. I think D can do much better... Note that temporaries are avoided when using the opXXXAssign() operators like +=. =========== Proposal =========== (1) Allow the compiler to assume that b = b + c can be replaced with b += c. (In C++, operator + and operator += are just symbols, the compiler doesn't know that there is any relationship between them). In the example above, this would allow the compiler to generate: T1 = B * C; T1 += D; T1 *= E; and we have eliminated two of the three temporaries. (2). Fill in the gaps in the operator overloading table by introducing opAddAssign_r, opSubAssign_r, etc. Just as A.opSubAssign(B) is the operation A -= B or equivalently A = A - B, similarly A.opSubAssign_r(B) would mean A = B - A. and would only occur when temporaries are generated in expressions. Like -=, it's an operation which can frequently be performed very efficiently, but at present the language has no way of expressing it. Our original example then becomes: T1 = B.opMul(C); T1.opAddAssign(D); T1.opMulAssign(E); T1.opSubAssign_r(A); X = T1; ... and all the useless temporaries are gone! More formally, when the expression tree for an expression is generated: With a binary operator XXX, operating on left & right nodes: if (the left node is *not* an original leaf node) { // the left node is a temporary, does not need to be preserved. // we don't care if the right node is a temporary or not look for opXXXAssign(). } else if (the the right node is not an original leaf node) { // the right node is a temporary look for opXXXAssign_r() } else { // both left and right nodes are leaf nodes, we have to // create a temporary look for opXXX(), just as it does now. } These rules also cope with the situation where temporaries are required: eg X = (A*B) + (C*D); becomes T1 = A*B; T2 = C*D; T1 += T2; X = T1; If this were implemented, it would permanently eradicate (for D) the most significant advantage which Fortran has managed to retain over object-oriented languages. And I really don't think it would be difficult to implement, or have negative side-effects. There are a couple of decisions to be made: (I) should the compiler use opAdd() and generate a temporary, if opAddAssign_r() doesn't exist, to preserve existing behaviour? I think the answer to this is YES. (II) should the compiler use opAdd() and generate a temporary, if oppAddAssign() doesn't exist, to preserve existing behaviour? Again, I'm inclined to answer YES. (III) If the code includes +=, and there is an opAdd() but no opAddAssign(), should the compiler accept this, and just generate an opAdd() followed by an assignment?? This would mean that opAdd() would generate the += operation as well as +, while opAddAssign() would be a performance enhancement. (It would still be possible to have opAddAssign() without opAdd(), to have += but not +, but it would not be possible to have + without +=). This would mean that += would be *purely* syntactic sugar. Decision III would be a little more difficult to implement and is of less obvious merit, I only mention it as a possibility. Comments? ]]> D语言模板最q的一些改q?/title> http://m.shnenglu.com/cpunion/archive/2006/03/15/4204.htmlqiezi qiezi Wed, 15 Mar 2006 09:03:00 GMT http://m.shnenglu.com/cpunion/archive/2006/03/15/4204.html http://m.shnenglu.com/cpunion/comments/4204.html http://m.shnenglu.com/cpunion/archive/2006/03/15/4204.html#Feedback 0 http://m.shnenglu.com/cpunion/comments/commentRss/4204.html http://m.shnenglu.com/cpunion/services/trackbacks/4204.html
函数模板参数cd推导Q?br>
template Square (T) { T Square (T t) { return t * t; } }
以前调用时必L式实例化Q?br>
writefln("The square of %s is %s" , 3, Square!(int )(3)); 现在可以使用自动推导了: writefln("The square of %s is %s" , 3, Square(3)); // T is deduced to be int cL板以前必这样写Q?br>template Bar (T) { class Bar { T member; } } 现在可以写ؓQ?br>class Bar (T) { T member; } 含义相同?br> ]]> 从CQ+到D http://m.shnenglu.com/cpunion/archive/2006/03/14/4129.htmlqiezi qiezi Tue, 14 Mar 2006 04:10:00 GMT http://m.shnenglu.com/cpunion/archive/2006/03/14/4129.html http://m.shnenglu.com/cpunion/comments/4129.html http://m.shnenglu.com/cpunion/archive/2006/03/14/4129.html#Feedback 0 http://m.shnenglu.com/cpunion/comments/commentRss/4129.html http://m.shnenglu.com/cpunion/services/trackbacks/4129.html 1 class Foo2 {3 &nbs... 阅读全文 ]]> DMD 0.149发布 http://m.shnenglu.com/cpunion/archive/2006/03/08/3888.htmlqiezi qiezi Wed, 08 Mar 2006 03:36:00 GMT http://m.shnenglu.com/cpunion/archive/2006/03/08/3888.html http://m.shnenglu.com/cpunion/comments/3888.html http://m.shnenglu.com/cpunion/archive/2006/03/08/3888.html#Feedback 0 http://m.shnenglu.com/cpunion/comments/commentRss/3888.html http://m.shnenglu.com/cpunion/services/trackbacks/3888.html 0.147中加入了match表达式,不过感觉用处太小了点Q果?.148中又L了?BR>0.148中去掉了bitcdQ增加了BitArraycdbool基本cd。on_scope语句是个比较重要的更新Q可用于在代码块l束、异常、成功执行时Q完成特定功能?BR>0.149中on_scope语句Ҏ了scope(...)?img src ="http://m.shnenglu.com/cpunion/aggbug/3888.html" width = "1" height = "1" /> ]]>DMD 0.141发布 http://m.shnenglu.com/cpunion/archive/2005/12/06/1558.htmlqiezi qiezi Tue, 06 Dec 2005 02:41:00 GMT http://m.shnenglu.com/cpunion/archive/2005/12/06/1558.html http://m.shnenglu.com/cpunion/comments/1558.html http://m.shnenglu.com/cpunion/archive/2005/12/06/1558.html#Feedback 2 http://m.shnenglu.com/cpunion/comments/commentRss/1558.html http://m.shnenglu.com/cpunion/services/trackbacks/1558.html What's New for D 0.141
Dec 1, 2005
New/Changed Features
The predefined version identifier D_InlineAsm has been changed to D_InlineAsm_X86 . The former made no sense, and although it is still defined, it is deprecated.
Added D code coverage analyzer .
Added .mangleof property for types, which gives the 'mangled' type name as a string.
Bugs Fixed
其中“D代码覆盖分析器”应该是很多人感兴趣的东西了Q下面是一个例?摘自http://digitalmars.com/d/code_coverage.html )Q?/P>
/* Eratosthenes Sieve prime number calculation. */ bit flags[8191 ]; int main() { int i, prime, k, count, iter; printf( " 10 iterations\n " ); for (iter = 1 ; iter <= 10 ; iter ++ ) { count = 0 ; flags[] = true ; for (i = 0 ; i < flags.length; i ++ ) { if (flags[i]) { prime = i + i + 3 ; k = i + prime; while (k < flags.length) { flags[k] = false ; k += prime; } count += 1 ; } } } printf ( " \n%d primes\n " , count); return 0 ; }
~译、运行:
dmd sieve - cov sieve
l果如下Q?BR>
|/* Eratosthenes Sieve prime number calculation. */ | |bit flags[8191]; | |int main() 5|{ int i, prime, k, count, iter; | 1| printf("10 iterations\n"); 22| for (iter = 1; iter <= 10; iter++) 10| { count = 0; 10| flags[] = true; 163840| for (i = 0; i < flags.length; i++) 81910| { if (flags[i]) 18990| { prime = i + i + 3; 18990| k = i + prime; 168980| while (k < flags.length) | { 149990| flags[k] = false; 149990| k += prime; | } 18990| count += 1; | } | } | } 1| printf ("\n%d primes\n", count); 1| return 0; |} sieve.d is 100% covered
另一个惊喜是mangleof属性,可以得到一个类型被~译器mangle后的名字。不知道mangle对应的中文翻译是什么?大概是“名字{换”吧。一Ҏ试代码:
import std.stdio; void test(); void test1( int n); void test2( int n); void main() { void function ( int , char []) f; void function ( int ) f1; void function () f2; writefln (f.mangleof); writefln (f1.mangleof); writefln (f2.mangleof); writefln ( int .mangleof); float a; writefln (a.mangleof); writefln (( & test).mangleof); writefln (( & test1).mangleof); writefln (( & test2).mangleof); writefln ( void .mangleof); }
~译执行l果如下Q?BR>
PFiAaZv PFiZv PFZv i f PFZv PFiZv PFiZv v
]]>DMD 0.140发布 http://m.shnenglu.com/cpunion/archive/2005/11/25/1304.htmlqiezi qiezi Fri, 25 Nov 2005 05:38:00 GMT http://m.shnenglu.com/cpunion/archive/2005/11/25/1304.html http://m.shnenglu.com/cpunion/comments/1304.html http://m.shnenglu.com/cpunion/archive/2005/11/25/1304.html#Feedback 0 http://m.shnenglu.com/cpunion/comments/commentRss/1304.html http://m.shnenglu.com/cpunion/services/trackbacks/1304.html Nov 23, 2005
New/Changed Features
Added std.string.soundex .
Added std.string.entab .
Added std.string.wrap .
Added std.string.abbrev .
Added std.windows.charset (thanks to Stewart Gordon, D/28246 ).
Added std.demangle to demangle D names.
Improved promotion of names inside templates.
Now allows floating point and string literals as template value arguments.
To support the previous, the name mangling of template instances has changed. This will necessitate recompilation of any code that uses templates.
std.utf.UtfError is now deprecated. Use std.utf.UtfException instead.
Bugs Fixed
比较感兴的是QҎ和字W串帔R作ؓ模板值参敎ͼ单测试了一下:
import std.stdio; template TFloat ( float F) { float value = F; } template TString ( char [] S) { char [] value = S; } void main() { alias TFloat ! ( 3.14f ) PI; writefln(PI.value); writefln(TString ! ( " hello " ).value); }
~译通过Q运行结果如下: 3.14 hello ]]>DMDScript脚本工具QDDL目 http://m.shnenglu.com/cpunion/archive/2005/11/20/1200.htmlqiezi qiezi Sat, 19 Nov 2005 16:20:00 GMT http://m.shnenglu.com/cpunion/archive/2005/11/20/1200.html http://m.shnenglu.com/cpunion/comments/1200.html http://m.shnenglu.com/cpunion/archive/2005/11/20/1200.html#Feedback 0 http://m.shnenglu.com/cpunion/comments/commentRss/1200.html http://m.shnenglu.com/cpunion/services/trackbacks/1200.html http://www.digitalmars.com/dscript看到详细信息Q另外有一个C++的实现版本?BR> 另外2个符合ECMA 262规范的脚本语a分别是Netscape的javascript和Microsoft的JScriptQ目前DMDScript和其?个不完全兼容Q不q效率要高一些。DMDScript提供了一个简单的试Q生?190以内的质敎ͼq代10ơ,在我的机器上Qjavascript执行耗时566毫秒QDMDScript执行耗时188毫秒Q整整快?倍?BR> 如果你想实现一个符合ECMA 262标准的脚本语aQ徏议看q䆾代码的实现吧Q比较简z,只有400多K。微软那份估计是很难看到了,Netscape那䆾用C写的Q代码大就有近3MQ宏也比较多Q看h要吃力一些?BR> DDL是dsource.org上的一个有的目Q它可以?obj?lib文g中加载代码ƈ执行Q目前支持COFF、OMF、ELF格式?img src ="http://m.shnenglu.com/cpunion/aggbug/1200.html" width = "1" height = "1" /> ]]> D语言的模?/title> http://m.shnenglu.com/cpunion/archive/2005/11/11/1083.htmlqiezi qiezi Fri, 11 Nov 2005 09:13:00 GMT http://m.shnenglu.com/cpunion/archive/2005/11/11/1083.html http://m.shnenglu.com/cpunion/comments/1083.html http://m.shnenglu.com/cpunion/archive/2005/11/11/1083.html#Feedback 0 http://m.shnenglu.com/cpunion/comments/commentRss/1083.html http://m.shnenglu.com/cpunion/services/trackbacks/1083.html 闲话说Q请看代码:
import std.stdio; template DelegateHandlers(HandlerType, FunctionType) { HandlerType[] handlers; FunctionType[] functions; void opAddAssign(HandlerType h) { handlers.length = handlers.length + 1 ; handlers[length - 1 ] = h; } void opAddAssign(FunctionType f) { functions.length = functions.length + 1 ; functions[length - 1 ] = f; } } template Delegate(Ret) { class Delegate { alias Ret delegate () HandlerType; alias Ret function () FunctionType; mixin DelegateHandlers ! (HandlerType, FunctionType); static if ( is (Ret: void )) { void opCall () { foreach (HandlerType handler; handlers) handler (); foreach (FunctionType _function; functions) _function (); } } else { Ret opCall () { Ret ret; foreach (HandlerType handler; handlers) ret = handler (); foreach (FunctionType _function; functions) ret = _function (); return ret; } } } } template Delegate(Ret, Arg1) { class Delegate { alias Ret delegate (Arg1) HandlerType; alias Ret function (Arg1) FunctionType; mixin DelegateHandlers ! (HandlerType, FunctionType); static if ( is (Ret: void )) { void opCall (Arg1 a1) { foreach (HandlerType handler; handlers) handler (a1); foreach (FunctionType _function; functions) _function (a1); } } else { Ret opCall (Arg1 a1) { Ret ret; foreach (HandlerType handler; handlers) ret = handler (a1); foreach (FunctionType _function; functions) ret = _function (a1); return ret; } } } } class Test { void test () { writefln ( " Test.test " ); } int test1 () { writefln ( " Test.test1 " ); return 1 ; } void test2( int v) { writefln ( " Test.test2 " ); } int test3( int v) { writefln ( " Test.test3 " ); return 7 ; } } void test_func () { writefln ( " test_func " ); } int test_func1 () { writefln ( " test_func1 " ); return 2 ; } void test_func2( int v) { writefln ( " test_func2 " ); } int test_func3( int v) { writefln ( " test_func3 " ); return 9 ; } void main() { Test t = new Test; alias Delegate ! ( void ) DDD; DDD d = new DDD; d += & t.test; d += & test_func; d (); alias Delegate ! ( int ) DDD1; DDD1 d1 = new DDD1; d1 += & t.test1; d1 += & test_func1; int a = d1 (); assert (a == 2 ); alias Delegate ! ( void , int ) DDD2; DDD2 d2 = new DDD2; d2 += & t.test2; d2 += & test_func2; d2 ( 1 ); alias Delegate ! ( int , int ) DDD3; DDD3 d3 = new DDD3; d3 += & t.test3; d3 += & test_func3; int b = d3 ( 2 ); assert (b == 9 ); }
非常q净Q非常简z,不是吗?q个只花了我10分钟旉来写。。?BR> D语言的委托非帔R效,有兴的可以试一下通过委托和直接调用之间的性能差别。上面这个自己实现的多分z֧托类Q效率也非常高,我的试l果是对于性能的媄响几乎可以忽略。想起那个历千辛万苦实现的CQ+多分z֧托类Q实现复杂、调试费时、运行效率还很低Q每每一惛_q心里那个难受啊。。。?BR> 再来看一下D语言强大的静态检查机Ӟ
template XXX ( int v) { int n = v; static assert (v > 3 ); } void main () { int n; n = XXX ! ( 4 ).n; // OK n = XXX ! ( 3 ).n; // ~译错误 }
同样很漂亮?BR> 如果你觉得提CZ息不够友好,可以修改为:
template XXX ( int v) { int n = v; static if (v <= 3 ) pragma (msg, " template value must > 3 " ); static assert (v > 3 ); }
q是~译时的错误提示Q?BR> Compiling test.d ... template value must > 3 D:\workspace\dace\test.d(94): static assert (3 > 3) is false D:\workspace\dace\test.d(173): template instance test.XXX!(3) error instantiating 我想以后有可能会扩充pragmaQ支持错误输出,q样׃用写重复的语句了Q可以简化成q样Q?BR>
template XXX ( int v) { int n = v; static if (v <= 3 ) pragma (error, " template value must > 3 " ); }
q样看v来更好。不q目前有很多重要Ҏ要实现Q这U玩意可能要很久以后才会加入了?img src ="http://m.shnenglu.com/cpunion/aggbug/1083.html" width = "1" height = "1" /> ]]> D语言调用ActiveXQ在H口中嵌入ActiveXQ?/title> http://m.shnenglu.com/cpunion/archive/2005/11/11/1061.htmlqiezi qiezi Fri, 11 Nov 2005 04:16:00 GMT http://m.shnenglu.com/cpunion/archive/2005/11/11/1061.html http://m.shnenglu.com/cpunion/comments/1061.html http://m.shnenglu.com/cpunion/archive/2005/11/11/1061.html#Feedback 1 http://m.shnenglu.com/cpunion/comments/commentRss/1061.html http://m.shnenglu.com/cpunion/services/trackbacks/1061.html 阅读全文 ]]> D语言中的in/inout/out参数 http://m.shnenglu.com/cpunion/archive/2005/11/10/1044.htmlqiezi qiezi Thu, 10 Nov 2005 06:51:00 GMT http://m.shnenglu.com/cpunion/archive/2005/11/10/1044.html http://m.shnenglu.com/cpunion/comments/1044.html http://m.shnenglu.com/cpunion/archive/2005/11/10/1044.html#Feedback 0 http://m.shnenglu.com/cpunion/comments/commentRss/1044.html http://m.shnenglu.com/cpunion/services/trackbacks/1044.html private import std.stdio, std.process; void test( int a, inout int b, out int c) { writefln(a); writefln(b); writefln(c); a = 3 ; b = 5 ; c = 7 ; } void main () { int a = 0 , b = 1 , c = 2 ; test(a, b, c); assert (a == 0 ); assert (b == 5 ); assert (c == 7 ); std.process.system( " pause " ); } 在上面的例子里,E序在test函数中的输出语句输出: 0 1 0 也就是说Qout参数取值是无意义的Q它只用于赋倹{?BR> q里有一个很大的问题Q调用test(a,b,c)Ӟ调用者对于c的D改变可能毫无知觉Q甚x为隐藏很qBUG。对此,许多人徏议加强检查,比如在调用时Q必L明inout/outQ?BR>
test(a, inout b, out c);
g能够起到一些警CZ用,不过q样一来,语法上倒不怎么l了?img src ="http://m.shnenglu.com/cpunion/aggbug/1044.html" width = "1" height = "1" /> ]]>DMD最q的一些更?/title> http://m.shnenglu.com/cpunion/archive/2005/11/10/1039.htmlqiezi qiezi Thu, 10 Nov 2005 04:12:00 GMT http://m.shnenglu.com/cpunion/archive/2005/11/10/1039.html http://m.shnenglu.com/cpunion/comments/1039.html http://m.shnenglu.com/cpunion/archive/2005/11/10/1039.html#Feedback 2 http://m.shnenglu.com/cpunion/comments/commentRss/1039.html http://m.shnenglu.com/cpunion/services/trackbacks/1039.html
char [] a = " abcde " [ 2 .. 3 ]; writefln(a); char b = " abcde " [ 3 ]; writefln(b);
另外修复了一些编译器和文生成的BUG?BR> v0.137的重要更新有Q?BR>隐式cd引用Q?BR>
auto c = " abcde " ; // c变量自动获得cdchar[]
extern(linkage)在内嵌函C使用
void test() { extern (C) test1(); }
其它更新则主要集中于~译器工作、文工兗库{,暂时q没有特别o人兴奋的Ҏ加入进来,比如Qstack tracing, relation api{?img src ="http://m.shnenglu.com/cpunion/aggbug/1039.html" width = "1" height = "1" /> ]]> D语言令h喜爱的几个地?/title> http://m.shnenglu.com/cpunion/archive/2005/11/02/902.htmlqiezi qiezi Wed, 02 Nov 2005 08:35:00 GMT http://m.shnenglu.com/cpunion/archive/2005/11/02/902.html http://m.shnenglu.com/cpunion/comments/902.html http://m.shnenglu.com/cpunion/archive/2005/11/02/902.html#Feedback 0 http://m.shnenglu.com/cpunion/comments/commentRss/902.html http://m.shnenglu.com/cpunion/services/trackbacks/902.html C/C++中的宏是很o人厌烦的QD不允许再使用它?BR> 2、好用的字符串常量表辑ּ?BR>除了cC的用双引号的字W串帔R表达式以外,q可以用`字符。可以用x"68 65 6C6C 6F"来表C?hello"Qr"ab\na"则忽略字W串帔R中{义字W的转义作用Q还可以在字W串帔R后加上c, w或d来指C字W串帔R是char[]cd、wchar[]cdq是dchar[]cd。可以用~q算W连?个字W串?BR> 3、数字?BR>数字可以直接使用Q还可以q样来定义:int a = 3_029_301_000; 数字直接?包括整数、QҎ、复?表达式中Q“_”字W是被忽略的。另外还直接提供了复数类型?BR> 4、提供定长数l、变长数l、关联数l?BR>int[3] a定义一个定长数l;int [] a定义一个变长数l;int[int]定义一个关联数l,键类型是intQ值类型是intQint[char[]] a定义一个关联数l,键类型是char[]Q值类型是intQ用非常方ѝ?BR>可以使用foreach来遍历数l:
foreach ( int index, int value; a) printf ( " %d: %d\n " , index, value); foreach ( char [] key, int value; a) printf ( " %.*s: %d\n " , index, value); 可以使用in操作W来判断某个值是否是兌数组的一个键Q?BR>
int [ char []] a; if ( " hello " in a) writefln ( " hello " ); 数组可以切片(slice)Q?BR>
int [] a; int [] b = a[ 1 .. 3 ]; int [] c = a[ 1 ..length]; {等。。。?BR> 5、其它还支持委托、函数指针、模ѝ异常、RAII、契U式~程、单元测试、with语句、auto/typeof、垃圑֛收、操作符重蝲、内联汇~、条件编译、嵌入到HTML{,它还标准化了ABI(q是C/C++最让h头痛的地方之一)。这些特性大部分都比较熟悉和实用Q下面简单介l一下条件编译和嵌入到HTML?BR> 6、条件编译?BR>在D中,可以使用version(VersionID)来进行条件编译:
version (Win32) { // } else { // .. } q可以用debug条gQ?BR>
debug { // } else { // } 或者: debug printf ("hello"); 静态条件编译:
const int n = 1 ; static if (n == 1 ) writefln ( " hello " ); else writefln (" world " );
cd查:
int n = 3 ; if ( is (n[])) writefln ( " like array " ); if ( is (n: int )) writefln ( " is an integer " );
7、嵌入HTML?BR>在一个HTML文g中,<code>?lt;/code>之间的部分可以当作D代码来编译。比如下面这D代码:
< h1 > This is a test </ h1 > < code > import std.c.stdio; int < font size =+1 >< b > main </ b ></ font > () { < span style ="color:red" > printf </ span > ( < u > " hello world\n " </ u > ); return 0; } </ code > < hr /> < h1 > End </ h1 >
把它存储为HTML文gQ可以直接用dmd~译器编译?img src ="http://m.shnenglu.com/cpunion/aggbug/902.html" width = "1" height = "1" /> ]]> 配置D语言~程环境 http://m.shnenglu.com/cpunion/archive/2005/11/02/892.htmlqiezi qiezi Wed, 02 Nov 2005 03:17:00 GMT http://m.shnenglu.com/cpunion/archive/2005/11/02/892.html http://m.shnenglu.com/cpunion/comments/892.html http://m.shnenglu.com/cpunion/archive/2005/11/02/892.html#Feedback 14 http://m.shnenglu.com/cpunion/comments/commentRss/892.html http://m.shnenglu.com/cpunion/services/trackbacks/892.html D语言的介l最好是?A >uframer的blogQ他译了D语言的大部分文档。当然由于D语言目前一直处于测试版Q文档和最新的~译器之间可能有很多不一致?BR> D语言的编译器目前?个,DMD和GDCQDMD比较Ҏ配置Q可以从http://www.digitalmars.com/d/dcompiler.html 下蝲最新版。下载的压羃包直接解压到L一个分区的根目录,q把\dm\bin和\dmd\bin加到PATH环境变量里即可用?BR> 写一个简单的D语言E序Q当然还是经典的HelloWorldE序Q?BR>
void main () { printf ( " Hello world!\n " ); }
和CE序基本上一栗把它保存ؓhello_world.d?BR> 下面直接在这个源文g所在的目录下,执行dmd hello_world.dQ即可编译出hello_world.exeQ执行它p在控制台打印出Hello world!?BR> 接下来到http://www.dsource.org/projects/build/ 下蝲buildE序Q这是在DC使用比较q泛的一个程序。由于最新的v2.09版已l发C一些严重的BUGQ所以最好到http://svn.dsource.org/projects/build/downloads/ 下蝲v2.08版。把下蝲?exe文g改名为build.exeq放|合适的文g夹下Qƈ讄PATH环境变量?为简单v见我是直接把它放在\dm\bin文g夹下) 下面试一下buildE序Q编写一个hello_world.brf文gQ保存在hello_world.d同一路径下,文g内容如下Q?BR>
- cleanup hello_world.d
然后执行build @hello_world卛_~译出hello_world.exe?/P>
akIDE是一个D语言的IDEQ可以到http://www.lessequal.com/akide 下蝲Q它只需要DMD支持?BR> D语言~译速度非常?q也是Walter Bright对C++不满的一个重要原?。dsource.org中的mango目包含755个D源文Ӟ但在我的机器上编译成.lib文g只需?U时间?BR> D语言性能也很不错Q有2D语言和C/C++、Java、C#的性能比较文章Q?A > http://mag.vchelp.net/200312/fanyi.htmhttp://mag.vchelp.net/200312/fanyi_2.htm 相关目介绍Q?BR>mango: q是一个专注于服务端编E的目Q目前主要由Kris开发、维护,实现了servletQ暂时还没有太复杂的功能Q不q很值得期待?BR>dwt: D语言的swt开发包Q界面开发首选。看qeclipse界面的应该有比较q印象。由于大部分代码是从java代码转换q来的,所以类名、接口等都没有改变?BR>dui: D语言的别一个界面开发包Q基于GTK?BR>build: 上面介绍q的build工具?BR>dcoder: Zvs.net的D语言语法高亮插g?BR>dsp: 全称是Dynamic Servlet Pages?BR> 以上目都可以在http://www.dsource.org/projects/ 扑ֈ详细资料?BR> DMDScript是一个类gJavaScript的脚本系l,可以?A >http://www.digitalmars.com/dscript/扑ֈ详细资料Q这个我q没有用过?BR> 最后附?个用dwt开发的界面(注:׃本h不习惯安装杀毒YӞ下蝲请先杀?Q?/FONT> 1、仿eclipse界面Q?BR>http://m.shnenglu.com/Files/cpunion/dummyeclipse.rar 2、dwt控g演示Q?BR>http://m.shnenglu.com/Files/cpunion/controlexample.rar 在windows xp主题下效果比较好。这2个程序在我的机器上分别只?.4M?.2M内存Q启动时间也不1U,不要被eclipse的启动时间吓坏了?BR>
扑ֈ了这2张图Q?BR> ]]>
ٸþþþþñŪ߳ |
þøݾƷԴվ |
re99þþƷ99 |
Ʒþþþþþþ |
ƷƷھþø |
˾Ʒþۺ |
þۺ77777鶹 |
AVһȾþ |
þùƷþ |
þþþþþþ66ƷƬ |
av˾þۺɫ |
˸ŮѲžþþ |
þAٸ۲ӰԺ |
þþƷˬӰ
|
91˾þþƷ |
AvƷþ |
Ʒþþþþþ |
þþƷAɫ |
츾þþ |
ݺݾþۺһ77777 |
þþþƷ |
Ʒþˬ |
˾þô߽ |
þ99Ʒþþþþ |
vaþþþͬ |
þ¶Ʒ |
ձþ |
Ʒһþò |
þþùƷ |
Ůþþþþ |
þþƷƷ |
99þþƷþþþþ崿 |
ƷŮٸavѾþ |
Ưޱ˾þþƷ |
þþþþþƷο |
þۺ77777鶹 |
þùƷƷ |
þþþþϸ |
Ʒþ |
ҹþƷþþþ |
ŷƷþ |