---
title: "内存 Memory"
description: "内存读写、句柄指针与原生调用"
---

---
title: 内存 Memory
description: 内存读写、句柄指针与原生调用
---

`sa` · 扩展 `CLEO` · 需 CLEO

内存读写、句柄 ↔ 指针、调用原生函数。

写法见 [CLEO Lua](/docs/cleo/syntax) / [Redux](/docs/cleo/syntax-redux)。

## 写内存

<Opcode id="0A8C" name="WRITE_MEMORY" member="Memory.Write">
往进程地址写入指定字节宽度的值。`vp` 为真时改页保护。地址 / 宽度错会崩。

```text
0A8C WRITE_MEMORY
in: address, size, value, vp
```

```lua
writeMemory(0xC0D090, 4, 1, true)
```

```js
Memory.write(address, size, value, vp)
```
</Opcode>

## 读内存

<Opcode id="0A8D" name="READ_MEMORY" member="Memory.Read">
从进程地址读取指定字节宽度。`vp` 控制是否改页保护。

```text
0A8D READ_MEMORY
in: address, size, vp
out: result
```

```lua
local money = readMemory(0xB7CE50, 4, false)
```

```js
const result = Memory.read(address, size, vp)
```
</Opcode>

## ped 句柄转指针

<Opcode id="0A96" name="GET_PED_POINTER" member="Memory.GetPedPointer">
角色句柄 → ped 结构体地址。

```text
0A96 GET_PED_POINTER
in: char
out: address
```

```lua
local pedPtr = getPedPointer(playerActor)
```

```js
const address = Memory.getPedPointer(char)
```
</Opcode>

## 载具句柄转指针

<Opcode id="0A97" name="GET_VEHICLE_POINTER" member="Memory.GetVehiclePointer">
载具句柄 → 载具结构体地址。

```text
0A97 GET_VEHICLE_POINTER
in: handle
out: address
```

```lua
local carPtr = getVehiclePointer(car)
```

```js
const address = Memory.getVehiclePointer(handle)
```
</Opcode>

## 物体句柄转指针

<Opcode id="0A98" name="GET_OBJECT_POINTER" member="Memory.GetObjectPointer">
物体句柄 → 物体结构体地址。

```text
0A98 GET_OBJECT_POINTER
in: object
out: address
```

```lua
local objPtr = getObjectPointer(obj)
```

```js
const address = Memory.getObjectPointer(object)
```
</Opcode>

## 当前脚本结构体

<Opcode id="0A9F" name="GET_THIS_SCRIPT_STRUCT" member="Memory.GetThisScriptStruct">
当前脚本结构体地址。

```text
0A9F GET_THIS_SCRIPT_STRUCT
out: address
```

```lua
local script = getThisScriptStruct()
```

```js
const address = Memory.getThisScriptStruct()
```
</Opcode>

## 调原生函数

<Opcode id="0AA5" name="CALL_FUNCTION" member="Memory.CallFunction">
按地址调原生函数。`pop=0` 当 stdcall；`pop=numArgs` 当 cdecl。后面跟变长参数。

```text
0AA5 CALL_FUNCTION
in: address, numArgs, pop, args...
```

```lua
callFunction(0x469390, 1, 1, arg0)
```

```js
Memory.callFunction(address, numArgs, pop, ...args)
```
</Opcode>

## 调 thiscall 方法

<Opcode id="0AA6" name="CALL_METHOD" member="Memory.CallMethod">
thiscall 调对象方法。`struct` 为 this，`pop` 固定 0。

```text
0AA6 CALL_METHOD
in: address, struct, numArgs, pop, args...
```

```lua
callMethod(0x6D5F10, thisPtr, 0, 0)
```

```js
Memory.callMethod(address, struct, numArgs, pop, ...args)
```
</Opcode>

## 调函数并取返回值

<Opcode id="0AA7" name="CALL_FUNCTION_RETURN" member="Memory.CallFunctionReturn">
同 `0AA5`，并取整数返回值。

```text
0AA7 CALL_FUNCTION_RETURN
in: address, numArgs, pop, args...
out: funcRet
```

```lua
local ret = callFunctionReturn(0x56E210, 0, 0)
```

```js
const funcRet = Memory.callFunctionReturn(address, numArgs, pop, ...args)
```
</Opcode>

## 调方法并取返回值

<Opcode id="0AA8" name="CALL_METHOD_RETURN" member="Memory.CallMethodReturn">
同 `0AA6`，并取返回值。

```text
0AA8 CALL_METHOD_RETURN
in: address, struct, numArgs, pop, args...
out: funcRet
```

```lua
local ret = callMethodReturn(0x4048E0, thisPtr, 0, 0)
```

```js
const funcRet = Memory.callMethodReturn(address, struct, numArgs, pop, ...args)
```
</Opcode>

## 按名找脚本结构体

<Opcode id="0AAA" name="GET_SCRIPT_STRUCT_NAMED" member="Memory.GetScriptStructNamed">
按脚本名找运行中脚本结构体；找不到为 0。

```text
0AAA GET_SCRIPT_STRUCT_NAMED
in: scriptName
out: address
```

```lua
local main = getScriptStructNamed("MAIN")
```

```js
const address = Memory.getScriptStructNamed(scriptName)
```
</Opcode>

## 标签地址

<Opcode id="0AC6" name="GET_LABEL_POINTER" member="Memory.GetLabelPointer">
标签代码位置的绝对地址。

```text
0AC6 GET_LABEL_POINTER
in: label
out: address
```

```lua
local addr = getLabelPointer(myFunc)
```

```js
const address = Memory.getLabelPointer(label)
```
</Opcode>

## 变量指针

<Opcode id="0AC7" name="GET_VAR_POINTER" member="Memory.GetVarPointer">
脚本变量在内存中的指针。

```text
0AC7 GET_VAR_POINTER
in: var
out: address
```

```lua
local p = getVarPointer(someVar)
```

```js
const address = Memory.getVarPointer(var)
```
</Opcode>

## 分配内存

<Opcode id="0AC8" name="ALLOCATE_MEMORY" member="Memory.Allocate">
分配内存块，返回地址。条件表示是否成功。

```text
0AC8 ALLOCATE_MEMORY
in: size
out: address
```

```lua
local buf = allocateMemory(256)
if buf ~= 0 then
  -- ok
end
```

```js
const address = Memory.allocate(size)
```
</Opcode>

## 释放内存

<Opcode id="0AC9" name="FREE_MEMORY" member="Memory.Free">
释放 `0AC8` 分配的内存。

```text
0AC9 FREE_MEMORY
in: address
```

```lua
freeMemory(buf)
```

```js
Memory.free(address)
```
</Opcode>

## 取浮点返回值

<Opcode id="0AE9" name="POP_FLOAT" member="Memory.PopFloat">
取出前一次 `0AA5`–`0AA8` 留下的浮点返回值。

```text
0AE9 POP_FLOAT
out: number
```

```lua
callFunction(0x123456, 0, 0)
local f = popFloat()
```

```js
const number = Memory.popFloat()
```
</Opcode>

## ped 指针转句柄

<Opcode id="0AEA" name="GET_PED_REF" member="Memory.GetPedRef">
ped 结构体地址 → 角色句柄。

```text
0AEA GET_PED_REF
in: address
out: handle
```

```lua
local handle = getPedRef(pedPtr)
```

```js
const handle = Memory.getPedRef(address)
```
</Opcode>

## 载具指针转句柄

<Opcode id="0AEB" name="GET_VEHICLE_REF" member="Memory.GetVehicleRef">
载具结构体地址 → 载具句柄。

```text
0AEB GET_VEHICLE_REF
in: address
out: handle
```

```lua
local handle = getVehicleRef(carPtr)
```

```js
const handle = Memory.getVehicleRef(address)
```
</Opcode>

## 物体指针转句柄

<Opcode id="0AEC" name="GET_OBJECT_REF" member="Memory.GetObjectRef">
物体结构体地址 → 物体句柄。

```text
0AEC GET_OBJECT_REF
in: address
out: handle
```

```lua
local handle = getObjectRef(objPtr)
```

```js
const handle = Memory.getObjectRef(address)
```
</Opcode>