小编Dan*_*all的帖子

修补实例类要求基类在同一个单元中?

我正在使用以下函数来修补现有对象的实例类.原因是我需要修补第三方类的受保护功能.

procedure PatchInstanceClass(Instance: TObject; NewClass: TClass);
type
  PClass = ^TClass;
begin
  if Assigned(Instance) and Assigned(NewClass)
    and NewClass.InheritsFrom(Instance.ClassType)
    and (NewClass.InstanceSize = Instance.InstanceSize) then
  begin
    PClass(Instance)^ := NewClass;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

但由于某种原因,只有在我自己的单元中定义基类时,代码才有效.为什么?是否有一种解决方法可以让它在没有它的情况下工作?

这不起作用

 unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, wwdblook, Wwdbdlg;

type
  TwwDBLookupComboDlg = class(Wwdbdlg.TwwDBLookupComboDlg); // This is necessary
  TForm1 = class(TForm)
    Button1: TButton;
    wwDBLookupComboDlg1: TwwDBLookupComboDlg;
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  TButtonEx = class(TButton)
  end;

  TwwDBLookupComboDlgEx = class(TwwDBLookupComboDlg)
  end; …
Run Code Online (Sandbox Code Playgroud)

delphi delphi-2007

16
推荐指数
1
解决办法
415
查看次数

字符/数字的乘法可以更高效吗?

我有以下代码,其中计算总和,基于一个非常大的系列.

该系列char *a是一个char数组,仅包含数字(0..9).

我想问一下是否有可能让代码更快.它目前是分布式计算应用程序的瓶颈.

一个小的复制代码.不是实际的代码,而是更简化.

int top = 999999999;

char *a;
a = (char*) calloc(top+1, sizeof(char));

// ... fill a with initial values ...

for (int i=0; i<10; ++i) {
    unsigned long long int sum = 0;

    for (m = 1, k = top; m < k; ++m, --k) {
        // Here is the bottle neck!!
        sum += a[m]*a[k];
    }

    printf("%d\n", sum);

    // ... Add something at the end of a, and increase top ...
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试过以下内容:

  1. 使用 …

c performance gcc

15
推荐指数
1
解决办法
256
查看次数

之后将类添加到类中

是否有可能加入和实施一个已经存在的类(这是一个后代的接口TInterfacedTInterfacedPersistent)来完成分离模型和视图到2个单位?

一个小小的解释为什么我需要这样的东西:

我正在开发一个树形结构,开放式模型,它具有以下结构(非常简化和不完整,只是为了说明问题的轮廓):

Database_Kernel.pas

TVMDNode = class(TInterfacedPersistent);
public
  class function ClassGUID: TGUID; virtual; abstract; // constant. used for RTTI

  property RawData: TBytes {...};
  constructor Create(ARawData: TBytes);

  function GetParent: TVMDNode;
  function GetChildNodes: TList<TVMDNode>;
end;
Run Code Online (Sandbox Code Playgroud)

Vendor_Specific_Stuff.pas

TImageNode = class(TVMDNode)
public
  class function ClassGUID: TGUID; override; // constant. used for RTTI

  // Will be interpreted out of the raw binary data of the inherited class
  property Image: TImage {...};
end;

TUTF8Node = class(TVMDNode)
public
  class function ClassGUID: TGUID; override; …
Run Code Online (Sandbox Code Playgroud)

delphi oop model-view-controller interface

11
推荐指数
1
解决办法
1158
查看次数

Linux/Bash:如何取消引用?

遵循命令

echo 'a b' 'c'
Run Code Online (Sandbox Code Playgroud)

输出

a b c
Run Code Online (Sandbox Code Playgroud)

但以下

X="'a b' 'c'"
echo $X;
Run Code Online (Sandbox Code Playgroud)

将结束

'a b' 'c'
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种取消引用$ X的方法,以便输出"ab c",但不会丢失合并的"ab"参数.(= 2个参数而不是3个,对命令'echo'没有区别,但对于其他命令如'cp'没有区别

linux bash shell command-line arguments

10
推荐指数
2
解决办法
8537
查看次数

Delphi:获取路由器的MAC

我正在使用Delphi,我想确定网络中网络设备的物理MAC地址,在本例中是路由器本身.

我的代码:

var
  idsnmp: tidsnmp;
  val:string;
begin
  idsnmp := tidsnmp.create;
  try
    idsnmp.QuickSend('.1.3.6.1.2.1.4.22.1.2', 'public', '10.0.0.1', val);
    showmessage(val);
  finally
    idsnmp.free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

其中10.0.0.1是我的路由器.

唉,QuickSend总是发送"由#10054连接重置".我试图修改MIB-OID,我也尝试了IP 127.0.0.1,哪个连接永远不会失败.我没有在Google上找到任何关于TIdSNMP的可用教程.:-(

关心Daniel Marschall

delphi networking snmp indy

8
推荐指数
2
解决办法
5045
查看次数

在备忘录中列出原始传感器数据

我想在Memo for Android中列出所有可用的原始传感器数据.

以下代码在过去几年中起作用,但它不适用于XE8.可能存在内部编译器错误.我有什么办法可以让它再次运作,还是有替代解决方案?

uses
  TypInfo;

type
  TOrientationSensorAccessor = class(TCustomOrientationSensor);
  TLocationSensorAccessor = class(TCustomLocationSensor);

procedure TForm2.Button1Click(Sender: TObject);
var
  p_location: TCustomLocationSensor.TProperty;
  p_orientation: TCustomOrientationSensor.TProperty;
  n, v: string;
begin
  Memo1.Lines.Clear;

  if Assigned(OrientationSensor1.Sensor) then
  begin
    if not OrientationSensor1.Sensor.Started then OrientationSensor1.Sensor.Start;

    // Error (only in XE8): Incompatible types 'TCustomLocationSensor.TProperty' and 'TCustomOrientationSensor.TProperty'
    // In XE7 it works.
    for p_orientation in OrientationSensor1.Sensor.AvailableProperties do
    begin
      n := 'OrientationSensor.'+GetEnumName(TypeInfo(TCustomOrientationSensor.TProperty), integer(p_orientation)) ;
      v := FloatToStr(TOrientationSensorAccessor(OrientationSensor1.Sensor).GetDoubleProperty(p_orientation));
      Memo1.Lines.Values[n] := v;
    end;
  end;

  if Assigned(LocationSensor1.Sensor) then
  begin
    if not LocationSensor1.Sensor.Started then LocationSensor1.Sensor.Start;
    for p_location …
Run Code Online (Sandbox Code Playgroud)

delphi android firemonkey delphi-xe8

7
推荐指数
1
解决办法
392
查看次数

在地图文件中解析AccessViolation的地址

我的一位用户报告了一些我想要分析的罕见的AccessViolations.

我有完全相同的源代码,所以我可以创建一个MAP文件.但我不知道如何在MAP文件中找到AccessViolation提供的地址.

(将来,我们希望使用像JclDebug这样的框架来创建可用的堆栈跟踪).

我已经设置了一个例子:

procedure CrashMe;
var
  k: TMemo; a: TButton;
begin
  k.Text := 'abc';
  k.Color := clBlack;
  k.Assign(a);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CrashMe;
end;
Run Code Online (Sandbox Code Playgroud)

访问冲突是:

地址004146CF.从地址B2D88B53读取.

在地图文件中,我找到以下内容:

 Start         Length     Name                   Class
 0001:00401000 000556A8H .text                   CODE
 0002:00457000 00000770H .itext                  ICODE
 0003:00458000 00001B0CH .data                   DATA
 0004:0045A000 00004CCCH .bss                    BSS
 0005:00000000 00000038H .tls                    TLS

 ....

 0001:000552F0       Unit1..TForm1
 0001:00055498       Unit1.CrashMe
 0004:00004CC8       Unit1.Form1
 0001:000554C8       Unit1.TForm1.Button1Click
Run Code Online (Sandbox Code Playgroud)

为什么AV说地址004146CF,而MAP文件说0001:00055498?

即使我减去CODE段的起始地址(0001),我仍然得到004146CF-00401000 = 136CF,这也不是我想要的.

我也试图通过搜索字符串":00414"找到错误地址,但它没有找到任何内容.

如何在MAP文件中查找AV中的地址?

delphi debugging debug-symbols

7
推荐指数
1
解决办法
1414
查看次数

Why does the program crash when using const string arguments?

My program has following code:

function FooBar(const s: string): string;
var
  sa: AnsiString;
begin

  // ..........................

  sa := AnsiString(s);
  sa := AnsiString(StringReplace(string(sa), '*', '=', [rfReplaceAll]));
  sa := AnsiString(StringReplace(string(sa), ' ', '+', [rfReplaceAll]));
  result := string(sa);

  // ..........................

end;
Run Code Online (Sandbox Code Playgroud)

I noticed that the program did crash "somewhere" and FastMM4 said that I had written to a freed object. As soon as I have commented out "const", the program did work.

I have read the Delphi documentation about const arguments, but I …

memory delphi string crash const

6
推荐指数
1
解决办法
467
查看次数

后台线程何时阻止终止进程?

我们的程序在程序开头创建一个后台线程.后台线程使用Indy进行一些数据库完整性检查并检查Internet中的内容.10秒后,后台线程应该完成,因为FreeOnTerminate为true,它也会自行清理.

我们注意到,在某些情况下,如果用户过快地关闭程序,则该过程仍然有效,直到后台线程完成.

由于我们无法完全重现该问题,因此我创建了一个演示项目来尝试一些事情:

type
  TBackgroundThread = class(TThread)
  protected
    procedure Execute; override;
  end;

{ TForm1 }

var
  bt: TBackgroundThread;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: integer;
begin
  // Create a background thread which runs X seconds and then terminates itself.
  bt := TBackgroundThread.Create(false);
  bt.FreeOnTerminate := true;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  // The user closes the app while the background thread is still active
  Sleep(2000);
  Close;
end;

{ TBackgroundThread }

procedure TBackgroundThread.Execute;
var
  i: integer;
  x: cardinal;
begin
  inherited;

  // Simulate some …
Run Code Online (Sandbox Code Playgroud)

delphi multithreading indy terminate

6
推荐指数
1
解决办法
977
查看次数

"Pentium-safe FDIV"...... 2014年?

每次我查看编译器设置时,我都会想到同样的问题:为什么Delphi的当前编译器仍然具有"Pentium-safe FDIV"编译器选项?

Pentium-FDIV-Bug是在1994年11月发现的,并没有出现在1995年的CPU模型中.此时的处理器可能只有Windows 95,98和Me的强大功能.据我所知,第一台带有133 MHz的Intel Pentium 1 CPU(因此足够快以达到Windows 2000的最低系统要求)于1995年6月发布,当然没有FDIV错误.

当前Delphi版本的VCL/RTL使用了古代操作系统中没有的Windows API.Windows 98和Me不适用于空的Delphi XE6 VCL应用程序; 我没有检查Delphi XE6的VCL/RTL是否已经破坏了Windows 2000兼容性,但我认为是这样.

那么,为什么Embarcadero保留了1994年使用的编译器开关,当时他们放弃了对2000年使用的操作系统的支持?因此,没有人会需要这个编译选项,因为受影响的CPU无法与VCL/RTL所需的操作系统兼容.

更新 ; 澄清问题:这个开关可能有用吗?或者编译器可能在内部忽略该选项,它只是保留旧项目文件的选项?

delphi compiler-construction cpu

6
推荐指数
2
解决办法
744
查看次数