我正在使用以下函数来修补现有对象的实例类.原因是我需要修补第三方类的受保护功能.
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) 我有以下代码,其中计算总和,基于一个非常大的系列.
该系列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)
我已经尝试过以下内容:
使用 …
是否有可能加入和实施一个已经存在的类(这是一个后代的接口TInterfaced或TInterfacedPersistent)来完成分离模型和视图到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) 遵循命令
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'没有区别
我正在使用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
我想在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) 我的一位用户报告了一些我想要分析的罕见的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中的地址?
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 …
我们的程序在程序开头创建一个后台线程.后台线程使用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的当前编译器仍然具有"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 ×8
indy ×2
android ×1
arguments ×1
bash ×1
c ×1
command-line ×1
const ×1
cpu ×1
crash ×1
debugging ×1
delphi-2007 ×1
delphi-xe8 ×1
firemonkey ×1
gcc ×1
interface ×1
linux ×1
memory ×1
networking ×1
oop ×1
performance ×1
shell ×1
snmp ×1
string ×1
terminate ×1