我想在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的哪些日志库?
如果你使用了多个,请尝试添加一个推理,为什么你喜欢一个而不是另一个.
我会在这个问题上添加建议以保持可读性.
通常,在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)?感谢Hallvard对运算符重载的精彩描述,我知道:
但是,我不知道的是'=','<=','<','<>','>'和'> ='运算符的名称.这些存在,我可以使用Delphi版本吗?
PS:我现在仍然使用Delphi 2009,所以如果2010年提供这些,我会有另一个强大的升级论据;-)
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调试器变得比以前慢了很多.
我在Delphi 2007和2009中都注意到了这一点,所以它似乎不属于Delphi本身......
是什么导致这种行为,我该如何防止这种情况?
我希望使用Delphi Debugger调试我没有代码的可执行文件.
WinDBG中和其他调试器在这种情况下,没有选择,因为给定的可执行文件全部调用到我的DLL,为此我做有代码,效果显着.我的最终目标是,在运行的可执行文件的功能中查看堆栈跟踪.
我确实有这些可执行文件的符号信息,所以我希望我可以为此编写自己的.RSM文件.这会有用吗?Delphi调试器会选择它能找到的任何.RSM文件吗?这是否意味着应该省略其他调试信息?
请注意,我需要调试许多可执行文件,并且对于所有这些,我使用适度高级的功能检测算法自己检测其中的符号.所以我的主要问题主要是如何编写.RSM文件.为此,我必须知道.RSM文件格式的结构.是否有可用的文档或示例代码向我展示如何创建这样的文件?
任何帮助表示赞赏!
PS:你可能想知道我为什么这么做:这都与Dxbx有关- 一个开源的Xbox1模拟器.有关详细信息,请参阅sourceforce 欢迎新会员!
我正在使用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版本问题有关但仍然不同;
我正在寻找一种方法来检测编译我的代码的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版本,因此任何图书馆和/或组件供应商也会对此感兴趣,我猜想.