如何访问私有成员变量和函数

原创 2007年01月28日 12:39:00

一说到修改 Delphi 源码或者访问对象的私有成员函数,很多人马上可以说出种种危害来否定我。这种做法我也提倡,但是有时候如果可以灵活运用,可以解决由于 Delphi 因为封装不正确而带来的问题。我在这里分享一些技巧:

1.     访问私有成员变量
如果是 protected 的变量,可以用如下方法访问:

type
  TSomeClassAccess = 
class(TSomeClass);

begin
  TSomeClassAccess(Object1).protected_Bool := False;
  TSomeClassAccess(Object1).protected_Int := 
0;
  ...
end;

如果是 private 的变量,那么就要当心了。因为涉及到偏移量。还要考虑不同 Delphi 版本的控件的内部成员可能也有变化。最简单的例子是:访问 TMenuItem 的第二个内部成员变量 FHandle

type
  THackMenuItem = 
class(TComponent)
  
protected //<-- change to protected 
    FxxxxCaption: AnsiString;
    FHandle: HMENU;
//<-- the property you want to access

  end;


begin
  THackMenuItem(AMenuItem).FHandle := 0;
  ...
end;

2.      访问私有成员函数
这个目前普遍的做法是偷梁换柱。就是把自己的函数地址替换成待修改函数的内存地址。不过其中涉及到了内存修改、地址偏移量……,具体做法可以参考 TntControls TntSystem.pas 安装系统补丁,或者是 Fastcode 控件包。当然这个替换是会出现副作用的:例如 AQTime 就无法测试安装过 TntSystem 补丁的程序。

3.      直接修改代码的实现
如果是运行库中的具体实现要修改,可以直接动源码,因为改动是implementation 的部分,不会影响到其它的调用该单元的部分。(注意:interface implementation 的内容不能直接修改,否则无法编译通过。)修改之后,勾选编译选项里面的 „Use Debug DCUs“,并编译程序,再将编译得到的 dcu 文件保存到编译目录下面。我一般创建2个目录:PatchedVCLs PreCompiled 放修改过的源码,和编译之后的版本。然后把这个2个目录定义到环境变量里面,这样只要在每个项目的路径设置中添加这些变量,就可以使用改动过的代码了。

4.      间接修改代码的实现
如果要在修改定义部分怎么办?方法3是肯定行不通了。因为所有引用到这个单元的单元也需要重新编译,但不是所有 Delphi 源码你都可以重新编译的。这种情况就伤脑筋了。我目前只可以修改很小一部分的。基本思路是在自己的程序里面定义需访问对象的扩展类和具体实现。然后释放原先对象实例,并以新扩展类重新创建实例。请参考 打入消息循环的另类方法


总结:
以上四种方法是我在修改 Delphi 库或者第三方控件时候所用到的。在修改源码的时候,尽量要考虑到代码的移植性。要做到最少量的修改,得到最好的效果。并且需要考虑修改的代码是否可以在不 同的 Delphi 版本中使用。我在实际项目中,修改了67个源码。(有时间的话,我会一一列出,有需要的可以问我索取。)同时也欢迎交流更多的修改方法,以及 Delphi 不正确封装的补丁。


题外话:

刚刚来自 CodeGear 的消息,Delphi 下个版本会引入了新的技术,直接修改声明部分的代码将变的可能

C++访问类的私有成员变量的方法(友元函数、友元类)

// win32Test.cpp : Defines the entry point for the console application. // #include "stdafx.h" class...
  • libaineu2004
  • libaineu2004
  • 2014-03-06 11:28:38
  • 9528

访问C++类对象中私有成员变量的方法

原则上,C++类中私有变量不允许在类之外的其他任何地方访问,一般来说功能完善的类都会提供get,set方法来操作类属性值,但如果没有get、set方法都没有提供,比如使用的是第三方提供的.o(或者动态...
  • wwb0111
  • wwb0111
  • 2012-05-26 15:29:55
  • 784

c++中类对象不能访问类的私有成员变量

c++中类对象不能访问类的私有成员变量  (2014-06-19 14:13:40) 转载▼ 标签:  股票 分类: C_Concept ...
  • zkl99999
  • zkl99999
  • 2015-08-25 15:13:09
  • 2831

c++访问私有(private)成员变量的常用方法

类的对象不能直接访问类声明的私有成员变量,否则破坏了信息隐藏的目的。 在C++中,为了防止某些数据成员或成员函数从外部被直接访问,可以将它们声明为private,这样编译器会阻止任何来自外部非友元的...
  • u010418035
  • u010418035
  • 2015-05-04 20:22:38
  • 9454

使用类的反射机制来访问类的私有成员变量

首先我们来看个实例吧,一般根据Java的语法,类的私有成员变量只能被内部的方法所访问;但是通过类的反射机制,却可以访问这个类的所有变量(包括私有成员变量), 我们这个实例吧。 import java....
  • Leonardo9029
  • Leonardo9029
  • 2015-03-16 16:25:38
  • 1605

私有成员变量的访问(类内与类外)

1 class CTest { 2 public: 3 CTest(int i); 4 CTest(const CTest& rhs); 5 CTest& opera...
  • u011978022
  • u011978022
  • 2015-05-11 19:22:31
  • 292

访问类私有成员变量

下面列举了“非类成员”访问“类私有成员变量”的3种方法:     1.通过类公有成员函数set(), get()写、读私有成员;     2.通过类公有成员函数get()获取私有成员的指针或引用,...
  • Since20140504
  • Since20140504
  • 2016-05-12 18:03:20
  • 1377

C++访问类中私有成员变量的方法

原则上,C++类中私有变量不允许在类之外的其他任何地方访问,一般来说功能完善的类都会提供get,set方法来操作类属性值,还有就是就是通过友元访问。但是!但如果没有get、set方法都没有提供,也没有...
  • sangni007
  • sangni007
  • 2013-04-08 17:26:40
  • 11348

通过操作地址的方法来访问C++类对象中私有成员变量

      原则上,C++类中私有变量不允许在类之外的其他任何地方访问,一般来说功能完善的类都会提供get,set方法来操作类属性值,但如果没有get、set方法都没有提供,比如使用的是第三方提供的....
  • xylary
  • xylary
  • 2007-03-06 15:22:00
  • 3061
收藏助手
不良信息举报
您举报文章:如何访问私有成员变量和函数
举报原因:
原因补充:

(最多只允许输入30个字)