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

查看:26
本文介绍了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.

我可以用正则表达式很容易地删除代码,但想不出添加它的方法(确定 procedure 之后的第一个 begin>function 并插入带有适当参数的代码).

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天全站免登陆