访问 _CopyArray 过程
有没有办法访问(和调用)像 _CopyArray 这样在单元系统的接口中定义的过程?
注意:我正在尝试创建一个例程来深度克隆任何动态数组,并且不使用 Delphi 2010(使用 Delphi 2007)。
我试图在不使用 Copy 的情况下解决这个问题的原因是,我只有一个动态数组所在的指针(即指针)加上一个 typeinfo 引用。我无法调用 Copy 函数,因为它隐式需要填写类型信息。
解决方案: 您需要通过将 _ 替换为 @ 并将其范围限定为 system 来引用它。
procedure CopyArray( dest, source, typeInfo: Pointer; cnt: Integer );
asm
PUSH dword ptr [EBP+8]
CALL system.@CopyArray
end;
type
PObject = ^TObject;
function TMessageRTTI.CloneDynArray( Source: Pointer; T: TTypeRecord ): Pointer;
var
TypeInfo: TTypeRecord;
L: Integer;
PObj: PObject;
PArr: PPointer;
begin
Assert( T.TypeKind = tkDynArray );
// set size of array
Result := nil;
L := Length( TIntegerDynArray( Source ) );
if L = 0 then Exit;
DynArraySetLength( Result, T.TypeInfo, 1, @L );
if Assigned( T.TypeData^.elType ) then TypeInfo := ByTypeInfo( T.TypeData^.elType^ ) else TypeInfo := nil;
if Assigned( TypeInfo ) then begin
case TypeInfo.TypeKind of
tkClass: begin
PObj := Result;
while L > 0 do begin
PObj^ := CloneObject( PObject( Source )^ );
Inc( PObject( Source ) );
Inc( PObj );
Dec( L );
end;
end;
tkDynArray: begin
PArr := Result;
while L > 0 do begin
PArr^ := CloneDynArray( PPointer( Source )^, TypeInfo );
Inc( PPointer( Source ) );
Inc( PArr );
Dec( L );
end;
end;
else CopyArray( Result, Source, TypeInfo.TypeInfo, L );
end;
end else begin
// We can simply clone the data
Move( Source^, Result^, L * T.ElementSize );
end;
end;
Is there a way to access (and call) procedures like _CopyArray that are defined in the interface in the unit System?
NB: I am trying to create a routine that makes a deep clone of any dynamic array, and do not use Delphi 2010 (using Delphi 2007).
The reason why I am trying to solve this without using Copy is the fact that I have only a pointer where the dynamic array is located (the pointer that is) plus a typeinfo reference. I cannot call the Copy function because it implicitly needs to fill in the typeinfo.
SOLUTION:
You need to reference it by replacing the _ with an @ and scoping it with system.
procedure CopyArray( dest, source, typeInfo: Pointer; cnt: Integer );
asm
PUSH dword ptr [EBP+8]
CALL system.@CopyArray
end;
type
PObject = ^TObject;
function TMessageRTTI.CloneDynArray( Source: Pointer; T: TTypeRecord ): Pointer;
var
TypeInfo: TTypeRecord;
L: Integer;
PObj: PObject;
PArr: PPointer;
begin
Assert( T.TypeKind = tkDynArray );
// set size of array
Result := nil;
L := Length( TIntegerDynArray( Source ) );
if L = 0 then Exit;
DynArraySetLength( Result, T.TypeInfo, 1, @L );
if Assigned( T.TypeData^.elType ) then TypeInfo := ByTypeInfo( T.TypeData^.elType^ ) else TypeInfo := nil;
if Assigned( TypeInfo ) then begin
case TypeInfo.TypeKind of
tkClass: begin
PObj := Result;
while L > 0 do begin
PObj^ := CloneObject( PObject( Source )^ );
Inc( PObject( Source ) );
Inc( PObj );
Dec( L );
end;
end;
tkDynArray: begin
PArr := Result;
while L > 0 do begin
PArr^ := CloneDynArray( PPointer( Source )^, TypeInfo );
Inc( PPointer( Source ) );
Inc( PArr );
Dec( L );
end;
end;
else CopyArray( Result, Source, TypeInfo.TypeInfo, L );
end;
end else begin
// We can simply clone the data
Move( Source^, Result^, L * T.ElementSize );
end;
end;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如 Serg 和 Andreas 所说,_ 例程都使用编译器魔法来提供功能,因此您应该使用
Copy
而不是_CopyArray
,is
而不是_IsClass
等。要直接回答您的问题,不,没有办法从其他单元中的 Delphi 代码调用这些例程。 RTL 的 makefile 在编译 System.pas 和 SysInit.pas 时会传递一个未记录的编译器开关,该开关告诉编译器将任何前导 _ 字符转换为 @。例如,
_CopyArray
变为@CopyArray
。您可以使用 BASM(汇编)块来调用它,但仅此而已。Like Serg and Andreas said, the _ routines all use compiler magic to provide functionality, so you should use
Copy
instead of_CopyArray
,is
instead of_IsClass
, etc.To directly answer your question though, no, there is no way to call those routines from Delphi code in other units. The makefile for the RTL passes an undocumented compiler switch when compiling System.pas and SysInit.pas which tells the compiler to convert any leading _ characters to @.
_CopyArray
becomes@CopyArray
, for example. You can call it using a BASM (assembly) block, but that's it.Andreas Rejbrand 的评论实际上是一个答案 - 当您复制复杂数组时,会自动调用 _CopyArray 过程。例如,在 _CopyArray 中设置断点并运行以下代码(应使用 debug .dcu 进行编译以激活断点):
The comment by Andreas Rejbrand is actually an answer - the _CopyArray procedure is called automaticaly when you copy complicated arrays. For example, set a breakpoint in _CopyArray and run the following code (should be compiled with debug .dcu to activate the breakpoint):