小编Rud*_*uis的帖子

在C++ Builder中是否有类似Delphi的扩展RTTI?

上下文

(下面的实际问题)

在Delphi中很容易

我经常将API头转换为Delphi.有时结构对齐有问题,或者我想念包装选项#pragma pack(push, 1).要检查我是否具有正确的对齐和大小,我使用扩展的RTTI通过这个简单的函数在我的翻译记录中显示偏移量:

procedure WriteOffsets(Info: Pointer);
var
  LContext: TRttiContext;
  LType: TRttiType;
  LField: TRttiField;
begin
  LType := LContext.GetType(Info);
  if Assigned(LType) then
    if LType.TypeKind = tkRecord then
    begin
      Writeln(('  ' + LType.QualifiedName + ' = record ').PadRight(48),
        ' // size ', LType.TypeSize);
      for LField in LType.GetFields do
        Writeln(('    ' + LField.Name + ': ' + LField.FieldType.Name + ';').PadRight(48),
          ' // offset ', LField.Offset);
      Writeln('  end;');
      Writeln;
    end
    else
    begin
      Writeln(LType.QualifiedName, ' is not a record'); …
Run Code Online (Sandbox Code Playgroud)

delphi c++builder

7
推荐指数
0
解决办法
135
查看次数

为什么我会得到"预期的E2026常量表达式"?

我必须在system32文件夹中移动一个文件,我使用了这段代码:

//-----------FUNCTION----------------
function GetWindowsSystemDir(): String;
var
  vlBuff: Array[0..MAX_PATH-1] of Char;
begin
  getSystemDirectory(vlBuff, MAX_PATH);
  Result := vlBuff;
end;
//-----------------------------------

const
  SMyFile = GetWindowsSystemDir+'\intructions.txt'; //error here, line 87
var
  S: TStringList;
begin
  S := TStringList.Create;
  try
    S.Add('intructions');
    S.SaveToFile(SMyFile);
  finally
    S.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

编译时给我错误:

[DCC Error] Unit1.pas(87): E2026 Constant expression expected
Run Code Online (Sandbox Code Playgroud)

谢谢.

delphi constants

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

C#中的接口委派

在Delphi中,我们可以将接口的实现委托给另一个类,我想知道这在C#中是否可行?

例如,我有接口IMyInterface,我说TMyClass实现了IMyInterface.但事实上并非如此.在内部,我可以使用implements关键字将接口实现委托给另一个类,而无需在TMyClass中声明每个方法.

c# delphi interface

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

检查乘以64位的常数参数

对于我的BigInteger代码,对于非常大的BigIntegers,输出结果很慢.所以现在我使用一个递归的分而治之算法,它仍然需要2'30"才能将当前最大的已知素数转换为超过2200万位数的十进制字符串(但只有135 ms将其转换为十六进制字符串) .

我仍然想减少时间,所以我需要一个例程,可以将NativeUInt(即32位平台上的UInt32,64位平台上的UInt64)除以100非常快.所以我使用乘法乘法.这在32位代码中工作正常,但我对64位不是100%肯定.

所以我的问题是:有没有办法检查乘以无符号64位值的乘法结果的可靠性?我通过简单地尝试使用UInt32的所有值(0 .. $ FFFFFFFF)来检查32位值.这花费了大约.3分钟.检查所有UInt64将花费比我的生命更长的时间.有没有办法检查使用的参数(恒定,换档后)是否可靠?

我注意到,如果所选参数错误(但接近),则DivMod100()总是失败$4000004B.是否有特殊值或范围来检查64位,所以我不必检查所有值?

我目前的代码:

const
{$IF DEFINED(WIN32)}
  // Checked
  Div100Const = UInt32(UInt64($1FFFFFFFFF) div 100 + 1);
  Div100PostShift = 5;
{$ELSEIF DEFINED(WIN64)}
  // Unchecked!!
  Div100Const = $A3D70A3D70A3D71; 
  // UInt64(UInt128($3 FFFF FFFF FFFF FFFF) div 100 + 1); 
  // UInt128 is fictive type.
  Div100PostShift = 2;
{$IFEND}

// Calculates X div 100 using multiplication by a constant, taking the
// high part of the 64 bit (or 128 bit) result …
Run Code Online (Sandbox Code Playgroud)

delphi x86-64 basm

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

匿名方法对TypeInfo的奇怪行为

对于需要泛型类型"family"的一段代码,我尝试使用它TypeInfo来检索所需的信息.

class function GetTypeKind<T>:TTypeKind;
Run Code Online (Sandbox Code Playgroud)

对于大多数类型,我可以解决这个问题.但匿名方法类型表现出意外.

我有一个匿名方法类型定义为:

TMethodProc = reference to procedure;
Run Code Online (Sandbox Code Playgroud)

我试着获取类型信息:

MyKind := GetTypeKind<TMethodProc>;

class function GetTypeKind<T>:TTypeKind;
var 
  TI: PTypeInfo;
begin
  TI := TypeInfo(T);

  ...
end;
Run Code Online (Sandbox Code Playgroud)

我知道匿名方法背后有一些编译魔术.但我得到以下结果:

TI.TypeData.IntfParent == IInterface
TI.TypeData.IntfFlags == [(out of bounds)6]
Run Code Online (Sandbox Code Playgroud)

标志有一个意外的值,TIntfFlag有三个值,所以6是意外的.GUID也不是指导.它有一个相同的8个字节的重复集,大多数是00.例如(0,225,48,180,0,0,0,0,0,225,48,180,0,0,0,0)

匿名方法是否被排除在TypeInfo某些调整之外或者是否有用.

另外,(奇怪的)6是一个无证的特征,还是可以是任何值?

delphi anonymous-methods typeinfo delphi-10.2-tokyo

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

这个stdout重定向如何工作?

下面的代码将stdout重定向到文件fname,然后重定向回原始标准输出.这对我来说可以.但我无法理解它是如何运作的.如果有人能帮助我理解我将会相信它.

    printf("\n This is console");
    fflush(stdout);
    fgetpos(stdout, &pos);
    fd = dup(fileno(stdout));
    freopen(fname, "a+", stdout);   

    printf("inside file op");  

    fflush(stdout);
    dup2(fd,fileno(stdout));
    close(fd);
    clearerr(stdout);
    fsetpos(stdout, &pos);
    printf("\nBack to Console");
Run Code Online (Sandbox Code Playgroud)

c c++ programming-languages

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

推荐指南/书籍阅读装配

最近我对读取汇编感兴趣,汇编由像ollydbg这样的反汇编程序显示.我想阅读这个程序集的原因是为了了解其他开发人员如何构建他们的应用程序或程序所具有的二进制文件的文件格式之类的东西.

这不像我是一个完整的编程新手,因为我已经使用C++和C#一段时间了.我对C++有了深刻的理解,因此整个指针概念对我来说很清楚.

我知道互联网上有大量的装配指南,但我不知道这个教程有多可靠:http://jakash3.wordpress.com/2010/04/24/x86-assembly-a-crash -course-tutorial-i /对我来说非常有用,这是一种教程,只是对指令的简短解释.这一点对我来说非常清楚,但它并未涵盖所有汇编代码.

我希望有人可以提供一个很好的指导/教程.

c++ assembly reverse-engineering

5
推荐指数
1
解决办法
1543
查看次数

如何在Delphi/Pascal中执行多行逐字字符串

在c#中,您可以使用多行文字字符串来创建一个字符串,该字符串跨越源代码中的物理换行符,例如

var someHtml = @"<table width="100%" border="0" cellspacing="0" cellpadding="5" align="center" class="txsbody">
    <tbody>
        <tr>
            <td width="15%" class="ttxb">&nbsp;</td>
            <td width="85%" class="ttxb"><b>COMPANY NAME</b></td>
        </tr>
    </tbody>
</table>";
Run Code Online (Sandbox Code Playgroud)

但是如何在不使用字符串连接的情况下在delphi中执行此操作,不是为了提高性能,而是为了在视觉上看起来像在c#中一样好而不是

Result :        = '<table width="100%" border="0" cellspacing="0" cellpadding="5" align="center" class="txsbody">';
Result : Result + '<tbody>';
Run Code Online (Sandbox Code Playgroud)

delphi string

5
推荐指数
1
解决办法
1581
查看次数

在大型文本文件中查找和替换文本(Delphi XE5)

我试图找到并替换文本文件中的文本.我过去能够用以下方法做到这一点:

procedure SmallFileFindAndReplace(FileName, Find, ReplaceWith: string);
begin
  with TStringList.Create do
    begin
    LoadFromFile(FileName);
    Text := StringReplace(Text, Find, ReplaceWith, [rfReplaceAll, rfIgnoreCase]);
    SaveToFile(FileName);
    Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

但是,当文件相对较小时,上述工作正常; 当文件大小类似于170 Mb时,上面的代码将导致以下错误:EOutOfMemory,消息"Out of memory"在此输入图像描述

我已经尝试了以下成功,但运行需要很长时间:

procedure Tfrm_Main.button_MakeReplacementClick(Sender: TObject);
var
  fs : TFileStream;
  s  : AnsiString;
  //s  : string;
begin
  fs := TFileStream.Create(edit_SQLFile.Text, fmOpenread or fmShareDenyNone);
  try
    SetLength(S, fs.Size);
    fs.ReadBuffer(S[1], fs.Size);
  finally
    fs.Free;
  end;
  s := StringReplace(s, edit_Find.Text, edit_Replace.Text, [rfReplaceAll, rfIgnoreCase]);
  fs := TFileStream.Create(edit_SQLFile.Text, fmCreate);
  try
    fs.WriteBuffer(S[1], Length(S));
  finally
    fs.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

我是"Streams"的新手并使用缓冲区.

有一个更好的方法吗?

谢谢.

delphi delphi-xe

5
推荐指数
1
解决办法
5008
查看次数

如何在Delphi中为变量分配语句?

下面的C代码如何在Delphi中完成?我尝试翻译,但似乎Delphi不允许使用此语法。基本上,我需要像在C代码中那样将函数分配给变量。在Delphi上怎么做?

这是参考的C代码:

void EnumWindowsTopToDown(HWND owner, WNDENUMPROC proc, LPARAM param)
{
    HWND currentWindow = GetTopWindow(owner);
    if (currentWindow == NULL)
        return;
    if ((currentWindow = GetWindow(currentWindow, GW_HWNDLAST)) == NULL)
        return;
    while (proc(currentWindow, param) && (currentWindow = GetWindow(currentWindow, GW_HWNDPREV)) != NULL);
}
Run Code Online (Sandbox Code Playgroud)

这是我的尝试:

type
  TFNWndEnumProc = function(_hwnd: HWND; _lParam: LPARAM): BOOL; stdcall;

    procedure EnumWindowsTopToDown(Owner: HWND; Proc: TFNWndEnumProc;
      _Param: LPARAM);
    var
      CurrentWindow: HWND;
    begin
      CurrentWindow := GetTopWindow(Owner);
      if CurrentWindow = 0 then
        Exit;

      CurrentWindow := GetWindow(CurrentWindow, GW_HWNDLAST);
      if CurrentWindow = 0 then
        Exit;

      while Proc(CurrentWindow, …
Run Code Online (Sandbox Code Playgroud)

delphi

5
推荐指数
1
解决办法
186
查看次数