Delphi中的元编程-向类的每个方法添加函数调用 [英] Meta-Programming in Delphi - Adding a function call to every method of a class
问题描述
我想向应用程序中添加一些工具,基本上我想向多个数据模块中的每个方法/事件的第一行添加一个函数调用,代码大致如下.
I'm wanting to add some instrumentation to an application, basically I want to add a function call as the first line to every method/event in a number of datamodules, the code roughly looks like.
procedure TSomeClass.SomeProcedure;
begin
ExecutionCounter(ClassName, 'SomeProcedure'); //This is what I want to insert.
//the rest of the procedure
end;
我可以手动执行数千种方法(可能要花费几个小时),但是我想知道是否有某种编程方式可以做到这一点.
I could do this manually to the thousands of methods (would likely take a few hours), but I was wondering if there was some programmatic way of doing this.
我可以使用正则表达式相当轻松地删除代码,但是想不出添加它的方法(确定procedure
或function
之后的第一个begin
并插入具有适当参数的代码)
I could remove the code fairly easily with a regular expression, but can't think of a way to add it (determine the first begin
after procedure
or function
and insert the code with the appropriate parameters).
对于Delphi中的AOP来说,这是一个很好的例子,但是它并没有得到很好的支持.
This would be a great case for AOP in Delp but it is not very well supported.
在某些背景下,我正在使用大型旧式应用程序服务器(DataSnap/DCOM),并且我想确定客户端仍在调用哪些功能. ExecutionCounter函数返回一个类作为接口,在类析构函数中它记录类名,方法名,增加该方法的执行计数和总运行时间(当然是在单独的线程中).
For some background, I'm working with a large legacy application server (DataSnap/DCOM) and I'm wanting to determine what functions are still being called by the client. The ExecutionCounter function returns a class as an interface, in the classes destructor it logs the class name, method name, increments the execution count and total running time for that method (in a separate thread of course).
推荐答案
最后,我手动完成了此操作.我添加了函数调用,共有647个方法.我的解决方案是使用CnPack中的脚本,我编写了以下脚本
In the end I did this somewhat manually. There were 647 methods that I added the function call. My solution was to use the scripting in CnPack, I wrote the following script
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或其他脚本语言.
It added ExecutionCounter(ClassName, 'TheCurrentMethodName');
as a new line at the current cursor position. I assigned it to CTRL+SHIFT+Q and worked my way through the application. Was a bit manual but took a bit over an hour to do. Would have liked to have come up with some mechanism to do it automatically - I guess I should probably learn Ruby or Perl or some other scripting language.
这篇关于Delphi中的元编程-向类的每个方法添加函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!