从DPR或Delphi中的其他函数/过程访问子函数/过程
据我所知 - 子例程对其父函数/过程具有私有访问模式,对吗?
有没有办法从“外部世界”- dpr 或单元中的其他函数/过程访问它们?
另外 - 哪种方式需要更多的计算和编译文件的空间?
例如:
function blablabla(parameter : tparameter) : abcde;
procedure xyz(par_ : tpar_);
begin
// ...
end;
begin
// ...
end;
procedure albalbalb(param : tparam) : www;
begin
xyz(par_ : tpar_); // is there any way to make this function public / published to access it therefore enabling to call it this way?
end;
// all text is random.
// also, is there way to call it from DPR in this manner?
// in C++ this can be done by specifing access mode and/or using "Friend" class .. but in DELPHI?
As much I know - Subroutines are with Private access mode to its parent unction / procedure, right?
Is there any way to access them from "outer-world" - dpr or other function / procedure in unit?
Also - which way takes more calcualtion and space to compiled file?
for example:
function blablabla(parameter : tparameter) : abcde;
procedure xyz(par_ : tpar_);
begin
// ...
end;
begin
// ...
end;
procedure albalbalb(param : tparam) : www;
begin
xyz(par_ : tpar_); // is there any way to make this function public / published to access it therefore enabling to call it this way?
end;
// all text is random.
// also, is there way to call it from DPR in this manner?
// in C++ this can be done by specifing access mode and/or using "Friend" class .. but in DELPHI?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
嵌套过程/函数 - 在另一个过程或函数中声明的过程/函数是一种特殊类型,因为它们可以访问它们嵌套的过程的堆栈(从而访问参数/局部变量)。因此,以及 Delphi 作用域规则,有无法在“父”过程之外访问它们。仅当您需要利用它们的特殊功能时才使用它们。 AFAIK Delphi/Pascal 是少数具有此功能的语言之一。从编译器的角度来看,该调用有一些额外的代码来允许访问父堆栈帧 IIRC。
AFAIK C++ 中的“朋友”类/函数是不同的 - 它们是类访问方法,而在您的示例中您使用的是简单的过程/函数。
在 Delphi 中,在同一单元中声明的所有过程/类都自动成为“友元”,除非在最新的 Delphi 版本中使用严格私有声明。例如,只要所有内容都在同一单元中,此代码片段就可以工作:
Nested procedures/functions - those declared inside another procedure or function, are a special type, because they can access the stack (and thereby parameters/local variables) of the procedure they are nested in. Because of this, and Delphi scope rules, there is no way to access them outside the "parent" procedure. You use them only if you need to take advantage of their special features. AFAIK Delphi/Pascal is one of the few languages to have this feature. From a compiler point of view the call has some extra code to allow accessing the parent stack frame, IIRC.
AFAIK "friend" class/functions in C++ are different - they are class access methods, while in your example you are using plain procedures/functions.
In Delphi all procedure/classes declared in the same unit are automatically "friend", unless strict private declarations are used in latest Delphi releases. For example this code snippets will work, as long everything is in the same unit:
注意:嵌入式例程<>私有/受保护的方法。
嵌入式例程即例程内的例程不能被外部例程访问。
您发布了一个嵌入式例程的示例,我也听说它们被称为“内部例程”。
这是另一个例子:
无论可见性如何,类上的方法都可以通过 RTTI 使用 Delphi 2010 进行调用。我在这篇文章中详细介绍了如何执行此操作。
如果在同一个 Unit 中,一个类上的方法可以被任何其他代码访问,无论可见性如何,除非它们被标记为 Strict Private。 这个问题有更多细节和很好的例子接受的答案。
如果您位于两个不同的单位,则可以使用受保护的方法 Hack 来访问受保护的方法。 本文对此进行了详细介绍。
Note: Embedded Routines <> Private/Protected Methods.
Embedded routines i.e. routines inside routines can not be accessed by external routines.
You have posted an example of an Embedded routine, I also heard them called Internal Routines.
Here is another example:
Regardless of visibility, methods on classes, can be called using Delphi 2010 via RTTI. I have detailed how to do this in this article.
If you are in the same Unit methods on a class can be accessed by any other code regardless of visibility, unless they are marked with Strict Private. This Question has more details and good example code in the accepted answer.
If you are in two different units you can use the Protected Method Hack to access the protected methods. Which is detailed in detailed in this article.
是的,您可以从外部世界访问嵌套在其他(父)子例程中的子例程。虽然这有点棘手。我在网上找到了这个指南。
如何将嵌套例程作为过程参数传递(32 位)
Delphi 通常不支持将嵌套例程作为过程参数传递:
明显的解决方法是传递过程地址并在 testpass 中对其进行类型转换:
但是有,上面示例中的一个陷阱 - 如果“内部”例程引用了在从 testpass 调用“内部”过程之前压入堆栈的任何变量(calltestpass 参数 - 如果有的话,或者 calltestpass 中的局部变量 - 如果有是任何),你的系统很可能崩溃:
简单来说,原因是堆栈帧排列
被测试通过例程和“内部”程序的调用“破坏”
错误地计算参数和局部变量位置
(请不要责怪德尔福)。
解决方法是在之前设置正确的堆栈上下文
“inner”是从“testpass”内部调用的。
请注意,测试通过例程的优化已关闭 - 优化通常不能很好地处理混合的 OP/汇编代码。
Yes, you can access a subroutine, which is nested in other (parent) subroutine, from the outer world. Though it's somewhat tricky. I've found this howto in the web.
How to pass nested routine as a procedural parameter (32 bit)
Delphi normally does not support passing nested routines as procedural parameters:
The obvious workaround is to pass procedure address and typecast it within testpass:
There is, however, a pitfall in the above example - if the "inner" routine references any variable that was pushed onto the stack before the "inner" procedure was called from testpass (calltestpass parameters - if there were any, or local variables in calltestpass - if there were any), your system most probably crashes:
The reason is, in simple words, that the stack frame arrangement
was "broken" by the call to testpass routine and "inner" procedure
incorrectly calculates parameters and local variables location
(do not blame Delphi, please).
The workaround is to set up the correct stack context before
"inner" is called from within "testpass".
Please note the optimization is switched OFF for testpass routine - optimization generally does not handle mixed OP/assembler code very well.
不,没有办法做到你所要求的。
xyz
函数只能由封闭的blablabla
函数调用。在该函数之外,xyz
不在作用域内,并且无法命名它。如果 C++ 允许嵌套函数,那么也没有任何方法可以引用它,就像没有办法从当前翻译单元外部引用具有静态链接的函数一样。如果您需要从
blablabla
函数外部调用xyz
,请将xyz
移到外部。如果您需要从当前单元外部调用它,那么您需要在单元的接口部分中声明该函数。然后,将该单元添加到外部代码的uses
子句中,您就可以从任意位置调用xyz
,甚至是 DPR 文件。如果
xyz
引用blablabla
函数的变量或参数,那么您需要将它们作为参数传递,因为xyz
将不再具有否则可以访问它们。访问说明符的概念在这里并不真正相关,因为我们不是在讨论类。单元具有接口和实现部分,它们与类的公共和私有部分并不相同。
No, there is no way to do what you're asking. The
xyz
function is callable only by the enclosingblablabla
function. Outside that function,xyz
is not in scope and there is no way to name it. If C++ allowed nested function, there wouldn't be any way to refer to it, either, just like there's no way to refer to functions with static linkage from outside the current translation unit.If you need to call
xyz
from outside theblablabla
function, then movexyz
outside. If you need to call it from outside the current unit, then you need to declare that function in the unit's interface section. Then, add that unit to the external code'suses
clause and you can callxyz
from wherever you want, even the DPR file.If
xyz
refers to variables or parameters of theblablabla
function, then you'll need to pass them in as parameters sincexyz
will no longer have access to them otherwise.The concept of access specifiers isn't really relevant here since we're not talking about classes. Units have interface and implementation sections, which aren't really the same as public and private sections of a class.