我想在应用程序中添加一些工具,基本上我想添加一个函数调用作为许多数据模块中每个方法/事件的第一行,代码大致如下。
procedure TSomeClass.SomeProcedure;
begin
ExecutionCounter(ClassName, 'SomeProcedure'); //This is what I want to insert.
//the rest of the procedure
end;
我可以手动完成数以千计的方法(可能需要几个小时),但我想知道是否有一些编程方式可以做到这一点。
我可以使用正则表达式轻松删除代码,但无法想出添加它的方法(确定begin
或procedure
之后的第一个function
并插入具有适当参数的代码)。
这对于Delphi中的AOP来说是一个很好的例子,但它得不到很好的支持。
对于某些背景,我正在使用大型遗留应用程序服务器(DataSnap / DCOM),并且我想确定客户端仍在调用哪些函数。 ExecutionCounter函数返回一个类作为接口,在类析构函数中它记录类名,方法名,增加该方法的执行次数和总运行时间(当然是在一个单独的线程中)。
答案 0 :(得分:3)
DSharp(https://bitbucket.org/sglienke/dsharp)有一些方面。所有方法都需要是虚拟的,这是一个非常真实的限制,但这可能是你可以使用的。
以下是他的AOP示例的链接:
对于你的例子,你会做这样的事情:
TMyAspect = class(TAspect)
public
class procedure DoBefore(Instance: TObject; Method: TRttiMethod;
const Args: TArray<TValue>; out DoInvoke: Boolean; out Result: TValue); override;
end;
实现可能看起来像这样:
class procedure TMyAspect.DoBefore(Instance: TObject; Method: TRttiMethod;
const Args: TArray<TValue>; out DoInvoke: Boolean; out Result: TValue);
begin
inherited;
ExecutionCounter(Instance.ClassName, Method.Name);
end;
你会把它挂在像这样的方法上:
AspectWeaver.AddAspect(TSomeClass, TMyAspect, 'SomeProcedure');
答案 1 :(得分:0)
最后我手动做了一些。有647个方法我添加了函数调用。我的解决方案是在CnPack中使用脚本,我编写了以下脚本
program InsertInstrumentation;
{
Note: Please Add this Script to Script Library, and Run it from the
Corresponding item of the Dropdown Menu under "Run" ToolButton in
Script Window. Or Assign a Shortcut to Run it.
}
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
var
EditView: IOTAEditView;
Proc : string;
dotpos : integer;
begin
EditView := CnOtaGetTopMostEditView(nil);
if EditView <> nil then
EditView.GetPosition.MoveBOL; // Move the cursor to the beginning of the line
proc := CnOtaGetCurrentProcedure;
dotPos := pos('.', proc);
if dotPos > 0 then //remove the class name if it is present
Delete(Proc, 1, dotPos);
IdeInsertTextIntoEditor(' ExecutionCounter(ClassName, ''' + Proc + ''');' + #13#10);
end.
它在当前光标位置添加了ExecutionCounter(ClassName, 'TheCurrentMethodName');
作为新行。我将它分配给了CTRL + SHIFT + Q并在我的应用程序中完成了工作。有点手动,但花了一个多小时才做。本来希望有一些机制可以自动完成 - 我想我应该学习Ruby或Perl或其他一些脚本语言。