提问关于C++和delphi数据结构在ASM中的有关问题
提问关于C++和delphi数据结构在ASM中的问题
c++中的一段代码
结构
typedef struct _RES_STR
{
DWORD dwID; // 物品固定ID
DWORD dwPos; // 物品在商店的位置(格数)
DWORD dwNum; // 购买的数量
} RES_STR, PRES_STR;
函数调用
__declspec(naked) void __stdcall Buy(DWORD dwNum, PRES_STR pRes)
{
__asm
{
pushad
push pRes
push dwNum
mov eax, 0x594BE0
call eax
add esp, 8
popad
}
}
我这样写成delphi
procedure TFrm_Pop.Button10Click(Sender: TObject);
type
RES_STR =packed record
dwID: DWORD ;
dwPos: DWORD ;
dwNum: DWORD ;
end;
var
Res:^RES_STR; ←←注意,如果把^去掉则无法编译成功
dwNum:Integer;
begin
Res.dwID:=1726;
Res.dwPos:=2;
Res.dwNum:=2;
dwNum:=1;
asm
pushad
push Res
push dwNum
mov eax,$594BE0
call eax
add esp, 8
popad
end;
end;
可以编译成功,但是在运行调用的时候却会出错(已经注入游戏了,而c++是正确的),请问是代码写错了还是什么原因
------解决方案--------------------
Res:^RES_STR;
是个指针了,你没有实际内容
type
pRES_STR = ^RES_STR;
var
Res:pRES_STR;
res := new(pRES_STR);
再试试
------解决方案--------------------
var
Res:^RES_STR; ←←注意,如果把^去掉则无法编译成功
dwNum:Integer;
begin
Res.dwID:=1726;
Res.dwPos:=2;
Res.dwNum:=2;
dwNum:=1;
你定义为指针类型,就应该为他分配内存啊
GetMem(Res,SizeOf(Res));
try
Res.dwID:=1726;
Res.dwPos:=2;
Res.dwNum:=2;
dwNum:=1;
...
finally
Freemem(Res);
end;
------解决方案--------------------
楼上两位说到点子上了,我忽略了主要问题,呵呵。
另外提一下
delphi中
RES_STR =packed record
dwID: DWORD ;
dwPos: DWORD ;
dwNum: DWORD ;
end;
相当于c++中
#pragma pack(push, 1)
typedef struct _RES_STR
{
DWORD dwID; // 物品固定ID
DWORD dwPos; // 物品在商店的位置(格数)
DWORD dwNum; // 购买的数量
} RES_STR, *PRES_STR;
不过这个结构体凑巧8字节对齐和1字节对齐的大小相同。。。
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
PRES_STR = ^RES_STR;
RES_STR = packed record
dwID: cardinal;
dwPos: cardinal;
dwNum: cardinal;
end;
procedure Foo(dwNum: Integer; Res: PRES_STR); stdcall;
begin
WriteLn(Res^.dwID);
WriteLn(Res^.dwPos);
c++中的一段代码
结构
typedef struct _RES_STR
{
DWORD dwID; // 物品固定ID
DWORD dwPos; // 物品在商店的位置(格数)
DWORD dwNum; // 购买的数量
} RES_STR, PRES_STR;
函数调用
__declspec(naked) void __stdcall Buy(DWORD dwNum, PRES_STR pRes)
{
__asm
{
pushad
push pRes
push dwNum
mov eax, 0x594BE0
call eax
add esp, 8
popad
}
}
我这样写成delphi
procedure TFrm_Pop.Button10Click(Sender: TObject);
type
RES_STR =packed record
dwID: DWORD ;
dwPos: DWORD ;
dwNum: DWORD ;
end;
var
Res:^RES_STR; ←←注意,如果把^去掉则无法编译成功
dwNum:Integer;
begin
Res.dwID:=1726;
Res.dwPos:=2;
Res.dwNum:=2;
dwNum:=1;
asm
pushad
push Res
push dwNum
mov eax,$594BE0
call eax
add esp, 8
popad
end;
end;
可以编译成功,但是在运行调用的时候却会出错(已经注入游戏了,而c++是正确的),请问是代码写错了还是什么原因
------解决方案--------------------
Res:^RES_STR;
是个指针了,你没有实际内容
type
pRES_STR = ^RES_STR;
var
Res:pRES_STR;
res := new(pRES_STR);
再试试
------解决方案--------------------
var
Res:^RES_STR; ←←注意,如果把^去掉则无法编译成功
dwNum:Integer;
begin
Res.dwID:=1726;
Res.dwPos:=2;
Res.dwNum:=2;
dwNum:=1;
你定义为指针类型,就应该为他分配内存啊
GetMem(Res,SizeOf(Res));
try
Res.dwID:=1726;
Res.dwPos:=2;
Res.dwNum:=2;
dwNum:=1;
...
finally
Freemem(Res);
end;
------解决方案--------------------
楼上两位说到点子上了,我忽略了主要问题,呵呵。
另外提一下
delphi中
RES_STR =packed record
dwID: DWORD ;
dwPos: DWORD ;
dwNum: DWORD ;
end;
相当于c++中
#pragma pack(push, 1)
typedef struct _RES_STR
{
DWORD dwID; // 物品固定ID
DWORD dwPos; // 物品在商店的位置(格数)
DWORD dwNum; // 购买的数量
} RES_STR, *PRES_STR;
不过这个结构体凑巧8字节对齐和1字节对齐的大小相同。。。
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
PRES_STR = ^RES_STR;
RES_STR = packed record
dwID: cardinal;
dwPos: cardinal;
dwNum: cardinal;
end;
procedure Foo(dwNum: Integer; Res: PRES_STR); stdcall;
begin
WriteLn(Res^.dwID);
WriteLn(Res^.dwPos);