Delphi中的元编程-向类的每个方法添加函数调用 [英] Meta-Programming in Delphi - Adding a function call to every method of a class

查看:90
本文介绍了Delphi中的元编程-向类的每个方法添加函数调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想向应用程序中添加一些工具,基本上我想向多个数据模块中的每个方法/事件的第一行添加一个函数调用,代码大致如下.

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.

我可以使用正则表达式相当轻松地删除代码,但是想不出添加它的方法(确定procedurefunction之后的第一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆