我刚刚将Delphi 2009 VCL/RTL代码与2010年代码进行了比较.
我注意到有很多$IF DEFINED(CLR)条件定义,他们在2010版本中获得了更多.
我认为这些条件定义已经废弃,因为Delphi .NET已经停产.VCL/RTL在Delphi Prism中是不是真的用过?或者是他们?
我正在尝试将我当前的Delphi 7 Win32代码转换为Delphi XE5 Android,只需要很少的更改,这样我的项目就可以从一系列Delphi版本和XE5的Android交叉编译到Win32.
从XE5开始,针对未来的语言会发生重大变化.其中一个变化是从零开始的字符串.
在具有基于1的字符串的旧版本中,以下代码是正确的:
function StripColor(aText: string): string;
begin
for I := 1 to Length(aText) do
Run Code Online (Sandbox Code Playgroud)
但现在这显然不对.建议的解决方案是使用:
for I := Low(aText) to High(aText) do
Run Code Online (Sandbox Code Playgroud)
这样,XE5 Win32处理基于1的字符串,而XE5 Android处理基于0的字符串.但是有一个问题 - 以前的Delphi版本(例如XE2)在这样的代码上输出错误:
E2198 Low cannot be applied to a long string
E2198 High cannot be applied to a long string
Run Code Online (Sandbox Code Playgroud)
我有很多字符串操作代码.我的问题是 - 如何修改和保持上面的代码可以在Delphi 7 Win32和Delphi XE5 Android中编译?
PS我知道我仍然可以在XE5中禁用ZEROBASEDSTRINGS定义,但这是不受欢迎的解决方案,因为在XE6中,这个定义可能会消失,并且所有字符串都将被强制为0.
函数返回匿名函数.我想将结果分配给变量.但是编译器认为我正在尝试分配函数而不是函数的结果.我该如何解决这个问题?
program Project9;
{$APPTYPE CONSOLE}
type
TMyEvent = reference to function: string;
var
v1: TMyEvent;
function GetHandler: TMyEvent;
begin
Result := function: string
begin
Result := '';
end;
end;
begin
v1 := GetHandler; // <- Incompatible types: 'TMyEvent' and 'Procedure'
end.
Run Code Online (Sandbox Code Playgroud)
注意:我确实有一个解决方法,但我希望在不引入包装器的情况下解决这个问题:
program Project9;
{$APPTYPE CONSOLE}
type
TMyEvent = reference to function: string;
TWrapper = record
FHandler: TMyEvent;
end;
var
v1: TMyEvent;
function GetHandler: TWrapper;
begin
Result.FHandler := function: string
begin
Result := '';
end;
end;
begin
v1 := GetHandler.FHandler; …Run Code Online (Sandbox Code Playgroud) delphi variables function-pointers function anonymous-methods
我们构建了一个使用包和组件的应用程序.当我们调试应用程序时,IDE中的"事件日志"通常会显示我们的BPL正在加载而没有调试信息("无调试信息").这没有意义,因为我们所有的包和EXE都是使用debug构建的.
_(each project) | Options | Compiling_
[ x ] Assertions
[ x ] Debug information
[ x ] Local symbols
Symbol reference info = "Reference info"
[ ] Use debug .dcus
[ x ] Use imported data references
_(each project) | Options | Linking_
[ x ] Debug information
Map file = Detailed
Run Code Online (Sandbox Code Playgroud)
我们有4个项目,都是使用运行时pacakges构建的:
观察到的问题
1)我们多次调试时,Components.bpl加载了调试信息,但"Local Variables"窗口中的所有值都是空白的.如果将鼠标悬停在代码中的变量上,则没有弹出窗口,"评估"窗口也不显示任何内容("结果"窗格始终为空白).
2)有时事件日志显示各种BPL的"无调试信息".例如,如果我们激活Plugin.bpl项目并设置它的Run | 将参数的主机应用程序作为MainApp.exe,然后按F9,除Plugin.bpl模块外,所有模块似乎都加载"Has Debug Info".加载时,事件日志显示"无调试信息".但是,如果我们关闭应用程序并立即按F9,它将再次运行它而不重新编译任何东西,这次Plugin.bpl加载了调试("有调试信息").
问题
1)什么会导致"局部变量"窗口不显示值?
2)当BPL符合调试并且所有调试文件(dcu,map等)都可用时,为什么BPL有时会在没有调试信息的情况下加载?
在Pascal中有两种类型声明:
前者只是创建方便的速记,如C中的typedef.别名是彼此兼容的,与原始类型兼容.创建的类型是故意不兼容的,并且在没有明确和不安全的情况下通过类型转换不能混合.
var
nn: NewName; nt: NewType; ot: OldType;
...
nn := ot; // should work
nt := ot; // should break with type safety violation error.
nt := NewType(ot); // Disabling type safety. Should work even if
// it has no sense semantically and types really ARE incompatible.
Run Code Online (Sandbox Code Playgroud)
根据我的理解,这些是Pascal基础知识.
现在让我们看一个特定类型和两个别名:
正如问题主题所说.我在Delphi中有一个控制台应用程序,它包含一个TTimer变量.我想要做的是为事件分配一个事件处理程序TTimer.OnTimer.我是Delphi的新手,我以前使用C#并且事件处理程序添加到事件是完全不同的.我发现一个人并不是简单地将一个过程作为一个处理程序分配给事件,你必须创建一个带有一个方法的虚拟类,该方法将成为处理程序,然后将此方法分配给该事件.这是我目前的代码:
program TimerTest;
{$APPTYPE CONSOLE}
uses
SysUtils,
extctrls;
type
TEventHandlers = class
procedure OnTimerTick(Sender : TObject);
end;
var
Timer : TTimer;
EventHandlers : TEventHandlers;
procedure TEventHandlers.OnTimerTick(Sender : TObject);
begin
writeln('Hello from TimerTick event');
end;
var
dummy:string;
begin
EventHandlers := TEventHandlers.Create();
Timer := TTimer.Create(nil);
Timer.Enabled := false;
Timer.Interval := 1000;
Timer.OnTimer := EventHandlers.OnTimerTick;
Timer.Enabled := true;
readln(dummy);
end.
Run Code Online (Sandbox Code Playgroud)
这似乎对我来说是正确的,但由于某种原因它不起作用.
编辑
看起来该TTimer组件将无法工作,因为控制台应用程序没有消息循环.有没有办法在我的应用程序中创建计时器?
我正在解析数据集并为TStringList我想要避免重复项分配值.我使用以下代码但仍插入重复项.
channelList := TStringList.Create;
channelList.Duplicates := dupIgnore;
try
dataset.First;
while not dataset.EOF do
begin
channelList.Add(dataset.FieldByName('CHANNEL_INT').AsString) ;
dataset.Next;
end;
Run Code Online (Sandbox Code Playgroud)
为什么要添加重复项?
在Delphi中,函数结果经常被实现为var-parameter(尽管QC票证不是out-parameter).
字符串常量基本上是具有负refcounter的变量,它应该抑制自动内存[de]分配.http://docwiki.embarcadero.com/RADStudio/XE3/en/Internal_Data_Formats#Long_String_Types
它确实压制了它:下面的代码不会泄漏.
type
TDealRecord = record
id_Type: Integer;
Price: extended;
Remark: String;
end;
const const_loop = 100000000;
function TestVar: TDealRecord;
//procedure TestVar;
var
Li: Integer;
LRec: TDealRecord;
begin
for Li := 1 to const_loop do begin
FillChar(Lrec,SizeOf(LRec), 0);
LRec.Remark := 'Test';
// FillChar(Result,SizeOf(Result), 0);
// Result.Remark := 'Test';
end;
end;
Run Code Online (Sandbox Code Playgroud)
但是改变操纵变量 - 它会立即开始大量泄漏.
function TestVar: TDealRecord;
//procedure TestVar;
var
Li: Integer;
LRec: TDealRecord;
begin
for Li := 1 to const_loop do begin
// FillChar(Lrec,SizeOf(LRec), 0);
// LRec.Remark := …Run Code Online (Sandbox Code Playgroud) 是否有可能使用Delphi语言(如果绝对必要,使用Prism)来开发Android平台的程序?
任何起点?
我正在寻找一个预定义的符号来编写这样的代码:
{$IFDEF LAZARUS}
// code compiles by fpc/lazarus
{$ELSE}
// code compiles by delphi
{$ENDIF}
Run Code Online (Sandbox Code Playgroud) delphi ×10
delphi-prism ×2
delphi-xe2 ×2
oxygene ×2
.net ×1
android ×1
bpl ×1
console ×1
debugging ×1
delphi-7 ×1
delphi-xe5 ×1
freepascal ×1
function ×1
generics ×1
lazarus ×1
packages ×1
refcounting ×1
string ×1
timer ×1
tstringlist ×1
variables ×1