如何在另一个函数中获取Delphi代码标签的地址?
我正在尝试将一些代码从Delphi5迁移到DelphiXe7-WIN64。 这个场景是最新的,Delphi不允许混合汇编和Delphi代码。 我也是个新手 原始代码:如何在另一个函数中获取Delphi代码标签的地址?,delphi,assembly,delphi-5,delphi-xe7,Delphi,Assembly,Delphi 5,Delphi Xe7,我正在尝试将一些代码从Delphi5迁移到DelphiXe7-WIN64。 这个场景是最新的,Delphi不允许混合汇编和Delphi代码。 我也是个新手 原始代码: function TclDbgHelpStackTracer.GetSymbolSearchPath(): string; var sPath: array[0..MAX_PATH] of char; mbi: MEMORY_BASIC_INFORMATION; pProc: Pointer; label l1; be
function TclDbgHelpStackTracer.GetSymbolSearchPath(): string;
var
sPath: array[0..MAX_PATH] of char;
mbi: MEMORY_BASIC_INFORMATION;
pProc: Pointer;
label l1;
begin
asm
mov eax, offset l1
mov pProc, eax
end;
l1:
Result := '';
if (GetEnvironmentVariable(SYMBOL_PATH) <> '') then
Result := GetEnvironmentVariable(SYMBOL_PATH) + ';';
if (GetEnvironmentVariable(ALTERNATE_SYMBOL_PATH) <> '') then
Result := Result + GetEnvironmentVariable(ALTERNATE_SYMBOL_PATH) + ';';
if (GetEnvironmentVariable('SystemRoot') <> '') then
Result := Result + GetEnvironmentVariable('SystemRoot') + ';';
VirtualQuery(pProc, mbi, sizeof(mbi));
GetModuleFileName(Cardinal(mbi.AllocationBase), sPath, MAX_PATH);
StrRScan(sPath, '\')^ := #0;
Result := Result + sPath + ';';
GetModuleFileName(0, sPath, MAX_PATH);
StrRScan(sPath, '\')^ := #0;
Result := Result + sPath;
end;
问题是如何传递l1的地址?或者还有其他方法可以做到这一点吗?问题中的代码实际上是在提取包含执行代码的模块的名称。您所需要的就是:
function TclDbgHelpStackTracer.GetSymbolSearchPath(): string;
function GetEnvPath(const Name: string): string;
var
Value: string;
begin
Value := GetEnvironmentVariable(Name);
if Value <> '' then
Result := Value + ';'
else
Result := '';
end;
function GetModulePath(Module: HMODULE): string;
begin
Result := ExtractFileDir(GetModuleName(Module));
end;
begin
Result :=
GetEnvPath(SYMBOL_PATH) +
GetEnvPath(ALTERNATE_SYMBOL_PATH) +
GetEnvPath('SystemRoot') +
GetModulePath(HInstance) + ';' +
GetModulePath(0);
end;
函数TclDbgHelpStackTracer.GetSymbolSearchPath():字符串;
函数GetEnvPath(const Name:string):string;
变量
值:字符串;
开始
值:=GetEnvironmentVariable(名称);
如果值为“”,则
结果:=值+';'
其他的
结果:='';
结束;
函数GetModulePath(模块:HMODULE):字符串;
开始
结果:=ExtractFileDir(GetModuleName(模块));
结束;
开始
结果:=
GetEnvPath(符号路径)+
GetEnvPath(备用符号路径)+
GetEnvPath('SystemRoot')+
GetModulePath(HInstance)+';'+
GetModulePath(0);
结束;
坦率地说,你问题中的asm
代码很奇怪。没有必要那样做。代码试图做的只是找到模块句柄,该句柄已经作为全局HInstance
变量可用
一般来说,您应该尽量避免使用
asm
。它使代码的可移植性降低,更难理解。有时使用asm
是正确的选择。这不是其中一种情况。卸下asm可获得启发。它还将有助于开始检查错误并停止截断指针。在您进入64位世界之前,您必须认识到指针是64位宽的。正如@rob kennedy在我(现已删除)的回答中所评论的,您可以通过使用全局HInstance
变量而不是基数(mbi.AllocationBase)来实现同样的目标
并抛出pProc
和汇编代码away@xmojmr我没有删除你的答案(我将在周一尝试修复,因为我是OOO。似乎我也丢失了@rob kennedy的评论。我自己删除了答案,因为它只是部分有用。以下是rob的评论:此代码调用VirtualQuery
以获取基本内存地址。它假定它将是整个DLL的基本地址,并进一步假定基本地址可以代表模块句柄。它传递该“句柄”到GetModuleFileName
获取DLL的名称。但是DLL在全局HInstance
变量中已经有了自己的句柄。根本不需要调用VirtualQuery
。“感谢您的回答。它看起来很完美。我们将在周一检查并接受它作为答案。”。
VirtualQuery(pProc, mbi, sizeof(mbi));
function TclDbgHelpStackTracer.GetSymbolSearchPath(): string;
function GetEnvPath(const Name: string): string;
var
Value: string;
begin
Value := GetEnvironmentVariable(Name);
if Value <> '' then
Result := Value + ';'
else
Result := '';
end;
function GetModulePath(Module: HMODULE): string;
begin
Result := ExtractFileDir(GetModuleName(Module));
end;
begin
Result :=
GetEnvPath(SYMBOL_PATH) +
GetEnvPath(ALTERNATE_SYMBOL_PATH) +
GetEnvPath('SystemRoot') +
GetModulePath(HInstance) + ';' +
GetModulePath(0);
end;