小编Pat*_*kvL的帖子

如何在Delphi记录中模拟位域?

我想在Delphi中声明一个包含与C中相同布局的记录.

对于那些感兴趣的人:此记录是Windows操作系统的LDT_ENTRY记录中的联合的一部分.(我需要在Delphi中使用此记录,因为我正在使用Delphi中的Xbox模拟器 - 请参阅sourceforge上的项目Dxbx).

无论如何,有问题的记录定义为:

    struct
    {
        DWORD   BaseMid : 8;
        DWORD   Type : 5;
        DWORD   Dpl : 2;
        DWORD   Pres : 1;
        DWORD   LimitHi : 4;
        DWORD   Sys : 1;
        DWORD   Reserved_0 : 1;
        DWORD   Default_Big : 1;
        DWORD   Granularity : 1;
        DWORD   BaseHi : 8;
    }
    Bits;
Run Code Online (Sandbox Code Playgroud)

据我所知,Delphi中没有可用的位域.我试过这个:

 Bits = record
      BaseMid: Byte; // 8 bits
      _Type: 0..31; // 5 bits
      Dpl: 0..3; // 2 bits
      Pres: Boolean; // 1 bit
      LimitHi: 0..15; // 4 bits
      Sys: Boolean; …
Run Code Online (Sandbox Code Playgroud)

delphi record bit-fields

25
推荐指数
3
解决办法
1万
查看次数

哪个日志库更好?

我在想; 您更喜欢Delphi的哪些日志库?

如果你使用了多个,请尝试添加一个推理,为什么你喜欢一个而不是另一个.

我会在这个问题上添加建议以保持可读性.

delphi logging

23
推荐指数
5
解决办法
9138
查看次数

带有'varargs'的函数如何检索堆栈的内容?

通常,在Delphi中,可以使用'array of const'方法声明具有可变数量参数的函数.但是,为了与用C编写的代码兼容,有一个未知的'varargs'指令可以添加到函数声明中(我在阅读Rudy的优秀" 融合陷阱 "文档时学到了这一点).

例如,可以在C中使用函数,声明如下:

void printf(const char *fmt, ...)
Run Code Online (Sandbox Code Playgroud)

在Delphi中,这将成为:

procedure printf(const fmt: PChar); varargs;
Run Code Online (Sandbox Code Playgroud)

我的问题是:在实现使用'varargs'指令定义的方法时,如何获取堆栈的内容?

我希望有一些工具存在,比如va_start(),va_arg()和va_end()函数的Dephi翻译,但我无法在任何地方找到它.

请帮忙!

PS:请不要讨论"为什么"或"const数组"的替代方案 - 我需要这个来为Xbox游戏中的函数编写类似C的补丁(参见Sourceforge上的Delphi Xbox模拟器项目'Dxbx'详情).

delphi variadic-functions

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

Delphi支持哪些类型的运算符重载?

我想知道什么样的操作符重载是可能的(以及什么版本的Delphi)?感谢Hallvard对运算符重载的精彩描述,我知道:

  • 添加(左,右:类型):类型(对于'+'运算符)
  • 减(左,右:类型):类型(对于' - '运算符)
  • 乘(左,右:类型):类型(对于'*'运算符)
  • 除(左,右:类型):类型(对于'/'运算符)
  • 隐式(aValue:Type):AnotherType和
  • 隐式(aValue:AnotherType):类型(对于隐式赋值:a:= b)
  • 显式(aValue:Type):AnotherType和
  • 显式(aValue:AnotherType):Type(用于'casts'的显式assignmetns:a:= Type(b)

但是,我不知道的是'=','<=','<','<>','>'和'> ='运算符的名称.这些存在,我可以使用Delphi版本吗?

PS:我现在仍然使用Delphi 2009,所以如果2010年提供这些,我会有另一个强大的升级论据;-)

delphi operator-overloading

16
推荐指数
2
解决办法
4277
查看次数

基本的Delphi类型如何相互关联?

Delphi长期以来支持一些基本的数字类型,我想知道它们是如何相互关联的.

在Delphi 2007中,我发现了这些声明(有些是冲突的,有些只是别名):

Types.pas:

DWORD = LongWord;
Largeint = Int64;
Run Code Online (Sandbox Code Playgroud)

getmem.inc:

DWORD = Integer;
Run Code Online (Sandbox Code Playgroud)

Windows.pas:

DWORD = Types.DWORD;
SHORT = Smallint;
UINT = LongWord;
ULONG = Cardinal;
LONGLONG = Int64;
TLargeInteger = Int64;
ULONGLONG = UInt64;
Run Code Online (Sandbox Code Playgroud)

这让我想到基本签名数字类型是SmallInt,Integer和Int64.无符号,有Byte,WORD和UInt64.但Cardinal和LongWord有什么区别?(顺便说一下,这些类型的原始和预期外壳是什么?)

是否有一个有符号8位整数(Int8)的类型?

// Int8 = ?unknown?;
UInt8 = Byte;
Int16 = SmallInt;
UInt16 = Word;
Int32 = Integer;
UInt32 = LongWord;
// Int64 already exists
// UInt64 already exists
Run Code Online (Sandbox Code Playgroud)

最后,我应该如何定义Int和UInt,特别是关于C/C++兼容性以及将来切换到其他平台(可能还有64位)?(当然,一个相关的问题是如何在64位Delphi中定义各种数字类型?)

delphi types

12
推荐指数
2
解决办法
2万
查看次数

为什么我的调试器这么慢?

一段时间以来,我的Delphi调试器变得比以前慢了很多.

我在Delphi 2007和2009中都注意到了这一点,所以它似乎不属于Delphi本身......

是什么导致这种行为,我该如何防止这种情况?

delphi debugging

8
推荐指数
1
解决办法
2195
查看次数

我可以自己生成一个.RSM文件供Delphi Debugger使用吗?

我希望使用Delphi Debugger调试我没有代码的可执行文件.

WinDBG中和其他调试器在这种情况下,没有选择,因为给定的可执行文件全部调用到我的DLL,为此我有代码,效果显着.我的最终目标是,在运行的可执行文件的功能中查看堆栈跟踪.

我确实有这些可执行文件的符号信息,所以我希望我可以为此编写自己的.RSM文件.这会有用吗?Delphi调试器会选择它能找到的任何.RSM文件吗?这是否意味着应该省略其他调试信息?

请注意,我需要调试许多可执行文件,并且对于所有这些,我使用适度高级的功能检测算法自己检测其中的符号.所以我的主要问题主要是如何编写.RSM文件.为此,我必须知道.RSM文件格式的结构.是否有可用的文档或示例代码向我展示如何创建这样的文件?

任何帮助表示赞赏!

PS:你可能想知道我为什么这么做:这都与Dxbx有关- 一个开源的Xbox1模拟器.有关详细信息,请参阅sourceforce 欢迎新会员!

delphi debugging

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

SetUnhandledExceptionFilter:继续执行1操作码

我正在使用Delphi中的Xbox1模拟器,因为我在本地CPU上运行游戏,我必须为游戏代码中可能出现的ring0指令创建故障保护.

为了能够捕获这些指令,我了解到SetUnhandledExceptionFilter可以注册一个将在非Delphi异常上调用的函数(前提是我将JITEnable设置为大于0的值).已注册的回调函数的签名如下:

function ExceptionFilter(E: LPEXCEPTION_POINTERS): Integer; stdcall;
Run Code Online (Sandbox Code Playgroud)

在该函数内部,我可以测试这样的非法指令:

// STATUS_PRIVILEGED_INSTRUCTION = $C0000096
if E.ExceptionRecord.ExceptionCode = STATUS_PRIVILEGED_INSTRUCTION then
Run Code Online (Sandbox Code Playgroud)

其中一个令人不快的指令是WVINDB($ 0F,$ 09),我可以这样检测:

 // See if the instruction pointer is a WBINVD opcode :
 if  (PAnsiChar(E.ExceptionRecord.ExceptionAddress)[0] = #$0F)
 and (PAnsiChar(E.ExceptionRecord.ExceptionAddress)[1] = #$09) then
Run Code Online (Sandbox Code Playgroud)

这一切都有效(假设我在调试器外部运行)但我无法让代码执行超出失败的指令 - 我尝试了这样:

  begin
    // Skip the WBINVD instruction, and continue execution :
    Inc(DWORD(E.ExceptionRecord.ExceptionAddress), 2);
    Result := EXCEPTION_CONTINUE_EXECUTION;
    Exit;
  end;
Run Code Online (Sandbox Code Playgroud)

唉,这不起作用.实际上,我会使用真正的指令指针(E.ContextRecord.Eip),但不知何故整个ContextRecord似乎没有填充.

我能做些什么使这个并不像预期的那样?

PS:当使用调试器运行时,我希望这段代码最终会出现在我的ExceptionFilter例程中,但事实并非如此 - 它只能在没有调试器的情况下运行; 为什么?

DebugHook := 0; // Act as if there's no debugger …
Run Code Online (Sandbox Code Playgroud)

delphi exception-handling

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

如何检测特定的Delphi构建?

这与另一个Delphi版本问题有关但仍然不同;

我正在寻找一种方法来检测编译我的代码的Delphi编译器的service-pack(或内部版本号).该jedi.inc是好的,但它并没有告诉我确切的版本.(我也不能在那里使用SUPPORTS_*定义,因为那些也与版本相关)

我需要这个,因为旧版本中存在一些错误(在这种情况下,它是Delphi 2009中_ValLong错误),这些错误已在以后的服务包中修复(在本例中为Delphi 2009 service pack 3).

目前我的代码中有各种检查,如下所示:

{$ IFDEF BUG_QC_68123}

但我不能在我的主要包含文件中说这个:

{$IFDEF DELPHI2009_UP}
  {$DEFINE BUG_QC_68123}
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)

...因为这将错过D2009SP3及更高版本不再有此错误的事实.

有任何想法吗?

PS:这可能也适用于较旧的(和较新的)Delphi版本,因此任何图书馆和/或组件供应商也会对此感兴趣,我猜想.

delphi version-detection

2
推荐指数
1
解决办法
1118
查看次数