我正在尝试编写一个函数TForm,根据用户设置配置返回两个实例之一:
function TfrmMain.GetCurrentRamEditFrm: TForm;
{ Get the RAM Editor Form instance according to currenttly-set protocol. }
begin
if frmSetup.GetCurrentProtocol() = FooBus then
result := RAM_Editor_FooBus.frmRAM_Editor_FooBus
else
result := RAM_Editor_SXcp.frmRAM_Editor_SXcp;
end;
Run Code Online (Sandbox Code Playgroud)
我需要这个函数,因为这个单元(Main.pas)在RAM编辑器表单中读/写了很多变量.
编译器在以下行上跳闸:
GetCurrentRamEditFrm().StatusBar1.Panels[1].Text := get_text(96);
带有错误消息: Undeclared identifier 'StatusBar1'
如果我明确地提供TForm实例,则没有错误:
RAM_Editor_SXcp.frmRAM_Editor_SXcp.StatusBar1.Panels[1].Text := get_text(96);
StatusBar 在两种形式中声明都是这样的:
type
TfrmRAM_Editor_SXcp = class(TForm)
StatusBar1: TStatusBar; // i.e. the scope is "published"
...
Run Code Online (Sandbox Code Playgroud)
有趣的是,编译器不介意以下内容:
GetCurrentRamEditFrm().show();
在Comm_Ethernet.dfm我声明一个类型的组件TServerSocket:
object frmCommEthernet: TfrmCommEthernet
object ServerSocket1: TServerSocket
Active = False
Port = 5555
ServerType = stNonBlocking
OnClientConnect = ServerSocket1ClientConnect
OnClientDisconnect = ServerSocket1ClientDisconnect
OnClientRead = ServerSocket1ClientRead
OnClientError = ServerSocket1ClientError
Left = 808
Top = 8
end
end
Run Code Online (Sandbox Code Playgroud)
TServerSocket是在 RTL 中的单元中声明的System.Win.ScktComp,但它在设计时似乎不可用,因为当我打开表单时,它会抱怨:
未找到 TServerSocket 类 [忽略] [取消] [全部忽略]
但是,我的项目编译并运行得很好(当此表单未在 IDE 中打开时)。我该如何摆脱这个错误?
文档定义System.Types.TByteDynArray为:
type TByteDynArray = array of Byte;
Run Code Online (Sandbox Code Playgroud)
如果我创建一个这样的例程:
procedure DoSomething(args: array of Byte);
begin
end;
Run Code Online (Sandbox Code Playgroud)
并调用例程,没有编译错误:
DoSomething([1, 2, 3]);
Run Code Online (Sandbox Code Playgroud)
但是,如果我将例程所采用的类型更改为:
procedure DoSomething(args: TByteDynArray);
Run Code Online (Sandbox Code Playgroud)
以相同方式调用函数会产生此编译错误:
[DCC Error] E2010 Incompatible types: 'TByteDynArray' and 'Set'
Run Code Online (Sandbox Code Playgroud)
为什么不array of Byte和TByteDynArray平等对待,显然它们应该是?我的代码库大量引用TByteDynArray,我想用这个方便的简写来代替创建这样的数组TByteDynArray.Create(1, 2, 3).
问题摘要:我指向一个类实例的指针,但是,当我尝试取消引用此指针并访问实例的属性时,我得到一个EAccessViolation异常,因为它取消引用"Nil".
我在单位范围内声明了指针:
private
CurrentRXFrame: ^TSXcpFrame;
Run Code Online (Sandbox Code Playgroud)
每次我的程序收到一个帧时,指针都会更新为指向这个最新的帧:
procedure TfrmFoo.OnReceivingFrame(Sender: TObject);
var
SXcpFrame: TSXcpFrame;
begin
SXcpFrame := TSXcpFrame.Create();
CurrentRXFrame := @SXcpFrame;
Run Code Online (Sandbox Code Playgroud)
我尝试在同一单元中的其他一些例程中取消引用指针,但得到一个异常:
// `FrameBytes` is merely a dynamic array of type "Byte".
PrintMsg(IntToHex(CurrentRXFrame^.FrameBytes[0], 2));
Run Code Online (Sandbox Code Playgroud)
例外:
raise exception class EAccessViolation with message 'Access violation at address 004DD1FE [...] Read of address 00000010.
如果我在此行之前设置断点,则相关变量评估为:
CurrentRXFrame := $18FD10
CurrentRXFrame^ := nil
CurrentRXFrame^.FrameBytes := Inaccessible value
Run Code Online (Sandbox Code Playgroud)
问题:如何TSxcpFrame通过指针访问类实例的属性?
我正在尝试解决的问题:我的程序用于System.Win.ScktComp.TServerSocket通过以太网与另一个本地进程通信.在从本地进程接收数据包和发送响应之间是100ms - 这不应该花费这么长时间.我正在尝试使用调试器逐步完成我的程序,以查看100ms的使用时间.
问题是如果我在调试器中获得当前时间,它显然会计算它在调试器的暂停状态下花费的时间.另一个问题是我的应用程序的相关部分是TTimer事件驱动的,因此当例程返回时,您不确定接下来将调用哪个例程.
我尝试:我可以放弃使用调试器和print当前时间到处都是像所有的OnTimer程序和其他活动.
更好的解决方案:使用调试器,获取CPU时间(不受调试器中暂停时间的影响),以确定丢失100ms的位置.