Apache配置虚拟主机
本文转自 http://www.ideagrace.com/html/doc/2005/10/27/00686.html
| |||||
©2005 Idea Grace |
本文转自 http://www.ideagrace.com/html/doc/2005/10/27/00686.html
| |||||
©2005 Idea Grace |
Posted by
马面祭司
at
11:59 PM
0
comments
其实Delphi为了速度的原因,对于接口是采用直接解析接口在实例中的偏移来得到的.这个可以从下面的代码中看到:
var
mInt: ITestInterface;
mInt2: ITestInterface2;
begin
mInt := TTestInterface2.Create;
mInt2 := TTestInterface2.Create;
end;
其中 mInt := TTestInterface2.Create 代码为:
mov dl, $01
mov eax, [$00452e4]
call TObject.Create
mov edx, eax
jz +$03
sub edx, -$0C
lea eax, [ebp-$04]
call @IntfCopy
而 mInt2 := TTestInterface2.Create 代码为:
mov dl, $01
mov eax, [$00452e4]
call TObject.Create
mov edx, eax
jz +$03
sub edx, -$0C
lea eax, [ebp-$08]
call @IntfCopy
但对于接口之间的转化时, CSDN的halfdream(哈欠) 兄说的很对, Delphi在call @IntfCast里调用了@QueryInterface, 而这里面的代码, 其实是在System的TObject对象的GetInterface这个方法中, 但这个方法有个问题, 它需要GUID, 但我们实际可以在Delphi中使用无GUID的接口, 那么就会发现, 根本无法进行转化
比如:
INoGUIDInterface = interface
procedure NoGUID;
end;
INoGUIDInterface2 = interface
procedure NoGUID2;
end;
var
mInt: INoGUIDInterface;
mInt2: INoGUIDInterface2;
begin
mInt := TTestNoGUIDInterface2.Create;
mInt.NoGUID;
mInt2 := mInt as INoGUIDInterface2;
mInt2.NoGUID2;
end;
编译就会出错了, Operator not applicable to this operand type 根本就不支持. 所以表明接口时还是随手加上GUID的比较好
Posted by
马面祭司
at
2:37 AM
0
comments
今天在发现delphi里的接口是不能强制转化的, 比如如下代码:
ITestInterface = interface(IUnknown)
['{DE8E7E63-BD1B-4BD8-B59A-43F4B2B3A3DC}']
procedure Chk;
end;
ITestInterface2 = interface(IUnknown)
['{3B47B113-4664-4CCC-9A69-E378F2D2363E}']
procedure Chk2;
end;
var
mInt: ITestInterface;
mInt2: ITestInterface2;
begin
mInt := TTestInterface2.Create;
mInt.Chk;
ITestInterface2(mInt).Chk2;
mInt2 := mInt as ITestInterface2;
mInt2.Chk2;
end;
从运行情况可以看出,在第一种情况 ITestInterface2(mInt).Chk2; 下,实际运行的还是ITestInterface下的procedure Chk;而第二种情况 mInt2 := mInt as ITestInterface2; 就能正确的运行ITestInterface2下的procedure Chk2;了.这是为什么呢?
原来这都出自Delphi的编译之手,在进行强制转化 ITestInterface2(mInt).Chk2; 时, 代码是:
mov eax, [ebp-$04]
mov edx, [eax]
call dword ptr [edx+$0c]
而进行 mInt.Chk; 调用时的代码也是这个,这说明强制转化时,编译器根本就没有把ITestInterface转化为ITestInterface2,而是理解为直接的对象强制转化,然后希望能在方法表里找到对应的方法,而且在对接口进行方法的解析时,也只是以方法的声明顺序,而不是实际的方法名来进行解析.所以在Chk为ITestInterface的第一个方法,而Chk2也为ITestInterface2的第一个方法时,就会直接的调用了ITestInterface的Chk,而不是ITestInterface2的Chk2.这个结论也可能通过下面这个实验来表明.
ITestInterface = interface(IUnknown)
['{DE8E7E63-BD1B-4BD8-B59A-43F4B2B3A3DC}']
procedure Chk;
end;
ITestInterface2 = interface(IUnknown)
['{3B47B113-4664-4CCC-9A69-E378F2D2363E}']
procedure Chk2;
procedure Chk22;
end;
var
mInt: ITestInterface;
mInt2: ITestInterface2;
begin
mInt := TTestInterface2.Create;
mInt.Chk;
ITestInterface2(mInt).Chk22;
mInt2 := mInt as ITestInterface2;
mInt2.Chk2;
end;
在这种情况下,就会报地址出错,那是因为ITestInterface根本就没有第二个方法.当然下面的代码也能说明问题
ITestInterface = interface(IUnknown)
['{DE8E7E63-BD1B-4BD8-B59A-43F4B2B3A3DC}']
procedure Chk;
procedure Chk1;
end;
ITestInterface2 = interface(IUnknown)
['{3B47B113-4664-4CCC-9A69-E378F2D2363E}']
procedure Chk2;
procedure Chk22;
end;
var
mInt: ITestInterface;
mInt2: ITestInterface2;
begin
mInt := TTestInterface2.Create;
mInt.Chk;
ITestInterface2(mInt).Chk22;
mInt2 := mInt as ITestInterface2;
mInt2.Chk2;
end;
在这种情况下,程序会调用ITestInterface的Chk1方法.
好上面说了强制转化时发生的情况,下面说用as来转化时发生的情况.
当用as来转化时,代码就变为:
lea eax, [ebp-$08]
mov edx, [ebp-$04]
mov ecx, $00452bc4
call @IntfCast
mov eax, [ebp-$08]
mov edx, [eax]
call dword prt [edx+$0c]
发现,在用as标志转化后,就会使编译器知道要在类实例中查找实际的接口ITestInterface2而不是用mInt所声明的ITestInteface.
以上说明Delphi7的编译器对接口的支持还是不够好,造成在强制转化时,不能正确的识别出要求的接口类型来.
Posted by
马面祭司
at
2:00 AM
0
comments
在这本书中, Part1的Enhancing the code的Code Retention一节中指出如果把
.class public explicit CharArray8 extends [mscorlib]System.ValueType { .size 8 }
这句放在
.field public static valuetype CharArray8 Format at FormatData
之前, 但在Even类之后的话,编译会出错, 但经过实际编译发现,这样子也是没有问题的, 看来要不是书上写错了,要不就是微软改进了它的编译器.
Posted by
马面祭司
at
8:19 AM
0
comments
Emacs for Windows: http://learn.tsinghua.edu.cn:8080/2002315162/index.html
这个网站上有emacs的windows版本, 直接就是可执行文件,而不用自己再去编译了.
Emacs 中文化指南: http://man.chinaunix.net/newsoft/Emac/book.html
这个网站实在是好,站长同学把他使用emacs的经验都写在上面了.很多东东都是可以直接复制来用.
emacs在windows上使用时,它没有建立一个缺省的.emacs配置文件,可以直接在emacs上使用~/.emacs来建立配置文件.
下面这个代码可以最大化emacs
(w32-send-sys-command 61488)
Posted by
马面祭司
at
10:23 PM
0
comments