如何访问私有成员变量和函数 (修正版)

原创 2007年04月09日 00:49:00
这篇文章介绍一些 Delphi 穿透 OOP 约束的技巧。
访问保护的 (protected) 变量
如果是某个类的保护变量,可以在任何地方,通过如下方法访问:
type
  TSomeClassAccess = 
class(TSomeClass);

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

 
访问私有的 (private) 变量
如果是某个类的私有变量,我们需要计算该变量在 VMT 中的偏移量。同时由于类声明可能在不同的 Delphi 版本中也有所不同,所以最好事先先检查一下源码。例:访问 TMenuItem 的第二个内部成员变量 FHandle
type
  THackMenuItem = 
class(TComponent)
  
protected //<-- change to protected 
    FxxxxCaption: AnsiString;
    FHandle: HMENU;
//<-- the property you want to access
begin
  THackMenuItem(AMenuItem).FHandle := 0;
  ...
end;

 
访问部分私有的 (private) 函数
访问私有函数要相对困难许多。据我所知只有定义时声明为 virtualoverridedynamic message 私有函数才可以被访问或替换。其实现原理和访问私有变量相似:先计算该函数在 VMT/DMT 中的偏移量然后把该内存地址替换成新函数的内存地址。具体做法可以参考 TntControls TntSystem.pas 安装系统补丁或者是 Fastcode 控件包。
友情提醒:(1) 通常私有函数中会涉及到一些访问其它的私有函数/变量。往往为了访问一个私有函数,还需要修改更多个私有函数/变量。相对比较复杂,也不很可靠。(2) 内存地址修改不当会引发于一些软件的冲突,如 AQTime
注:如果变量定义时未设置关键字 strict,同一个单元里面的所有类的内部变量/函数可以直接相互访问。这个是 Delphi 开的一个不大不小的后门。
 
增加私有的 (private) 函数 (a)
我们真的需要吗?有时候要!比如我在写一个 Dunit 单元测试的时候,需要接受 WM_COPYDATA 消息。但是这个消息是发送给 GUITestRunner 的,我必须打入 GUITestRunner 才可以得到相应消息。实现方法和访问私有函数类似,我们计算 VMT/DMT 的长度,在尾端增加一个新的函数指针。我在网上找到一篇文章说的比较详细,请点击这里查看。这个方法有个限制:这个修改不是编译期完成的,你必须在类实例化之后,才进行修改。如果这个类被频繁使用,这个做法显然有些麻烦。如果能把这段修改代码放如类的构析函数中,问题就迎刃而解了。我在假想:我们是否可以使用介绍3中引入的方法,实现这个……

增加私有的 (private) 函数 (b)
还有一种更干净的修改方法,我们定义一个同名的类来欺骗编译器。例:我们创建一个新的单元,名为 GUITestRunnerPatch.pas
type
  THackGUITestRunner = 
class(GUITestRunner.TGUITestRunner)
  
private
    procedure WMCopyData(var Msg: TWMCopyData);
message WM_COPYDATA; //<-- the method you want to append
  end;

在需要使用GUITestRunner 的地方加上新的GUITestRunnerPatch。注意:一定要在其之后,否则编译器不会调用你修改过的这个类,而是调用了原先的那个。
 
总结:
在进入 Delphi 的内部世界时,我们要尽可能的考虑代码的移植性和通用性,要以少量修改换回最佳效果。如果上面介绍的修修补补不能解决你的问题,当然你也可以直接修改 Delphi 的控件源码。修改之后,勾选编译选项里面的 „Use Debug DCUs“,并编译程序,再将编译得到的 dcu 文件保存到编译目录下面。我一般创建2个目录:PatchedVCLs PreCompiled 放修改过的源码,和编译之后的版本。然后把这个2个目录定义到环境变量里面,这样只要在每个项目的路径设置中添加这些变量,就可以使用改动过的代码了。如果本文不正确的地方,欢迎拍砖。
 

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

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

再探私有/公有静态成员变量与私有静态成员方法

问题1: 为什么在类内的静态成员定义后,要到类的外部在定义和初始化? 问题2:为什么类的静态成员在类外部的定义只能一次? 问题3:私有的静态成员变量如何初始化,访问权限还是私有么? 问题4:在程序执行...
  • tianjian789
  • tianjian789
  • 2015年09月06日 12:20
  • 1979

C++中类的访问权限针对的是类而不是对象!(为什么类中的函数可以访问对象的私有成员?)

我们首先看一段程序:class A { private: int i; public: A(int i): i(i) {} void print(A a) { ...
  • fukaibo121
  • fukaibo121
  • 2017年06月22日 21:18
  • 924

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

// win32Test.cpp : Defines the entry point for the console application. // #include "stdafx.h" class...
  • libaineu2004
  • libaineu2004
  • 2014年03月06日 11:28
  • 8850

Python中定义“私有”成员变量和成员函数

参考连接:http://docs.python.org/2/tutorial/classes.html    http://www.pythonclub.org/python-class/privat...
  • doufei_ccst
  • doufei_ccst
  • 2013年06月22日 19:29
  • 14354

对象能够直接访问其私有成员变量

转自:http://www.cnblogs.com/dwdxdy/archive/2012/07/17/2595741.html【C++】 私有成员变量的理解 私有成员变量的概念,在脑海中的...
  • CHENGUANCHI
  • CHENGUANCHI
  • 2014年02月21日 13:49
  • 2397

关于类成员函数中访问同类对象的私有成员

原址:http://wenku.baidu.com/view/4e13d5343968011ca300912c.html (注释: 为了尊重原作者,在不改变内容的前提下,我进行了格式和内容的编辑,...
  • johnnyelf83
  • johnnyelf83
  • 2013年06月22日 16:11
  • 3661

解决“使用google test做单元测试(unit test)中访问类的私有成员”的几种方法

在使用google test做单元测试(unit test)中,有时候会碰到访问类的私有成员, 本文 只给出了两个常用的方法。...
  • wlqingwei
  • wlqingwei
  • 2015年04月10日 17:30
  • 1280

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

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

c++静态变量,静态函数,私有静态变量的使用小记

自从上了小学才发现,记忆力大不如前了,看来小的时候没有开发出来,导致记忆模块荒凉遍野,现在很多学过,记过,用过的东西,一段时间以后发现除了有些印象外,再无其他,所以正证明那句话:“好记性不如烂笔头”。...
  • lxp116
  • lxp116
  • 2014年02月20日 11:06
  • 4143
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:如何访问私有成员变量和函数 (修正版)
举报原因:
原因补充:

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