C++转C#调用ReadProcessMemory传入GameVector结构体报错如何解决
问题原因
你当前报错的核心原因有两点:
- 你当前定义的
ReadProcessMemory的P/Invoke签名第三个参数类型为byte[],无法直接接收自定义的GameVector结构体 - C#中值类型默认是传值逻辑,你要修改外部传入的
vecInfo需要加ref修饰,对应C++的引用传递逻辑
解决方案
方案1(推荐,最简洁):新增适配结构体的P/Invoke重载
首先给GameVector结构体加内存布局控制特性,保证和C++侧布局完全一致:
[StructLayout(LayoutKind.Sequential)] // 强制按定义顺序排布字段内存,避免C#自动调整偏移 struct GameVector { float x, z, y; public static GameVector operator +(GameVector ImpliedObject, GameVector vSome) { return new GameVector() { x = ImpliedObject.x + vSome.x, z = vSome.z, y = ImpliedObject.y + vSome.y }; } public static GameVector operator -(GameVector ImpliedObject, GameVector vSome) { return new GameVector() { x = ImpliedObject.x - vSome.x, z = ImpliedObject.z, y = ImpliedObject.y - vSome.y }; } }
新增ReadProcessMemory的重载签名,直接适配结构体读取:
[DllImport("kernel32.dll")] static extern bool ReadProcessMemory ( IntPtr hProcess, IntPtr lpBaseAddress, out GameVector lpBuffer, int nSize, IntPtr lpNumberOfBytesRead );
修改GetSpawnPosition方法:
private unsafe void GetSpawnPosition(GameInfo gInfo, ref GameVector vecInfo) { if (!ReadProcessMemory(gInfo.hProc, (IntPtr)(gInfo.dwUnityPlayer + m_vecSpawn), out vecInfo, sizeof(GameVector), IntPtr.Zero)) { Console.WriteLine("Couldnt read spawn cords!"); return; // 原代码的break语法错误,无外层循环时不能在if块内使用break } }
方案2:复用现有byte[]类型的P/Invoke签名,读完字节数组再转结构体
如果不想新增P/Invoke重载,可以先读入字节数组,再手动反序列化为结构体:
首先实现字节数组转结构体的通用方法:
public static T BytesToStruct<T>(byte[] bytes) where T : struct { int structSize = Marshal.SizeOf<T>(); IntPtr allocPtr = Marshal.AllocHGlobal(structSize); try { Marshal.Copy(bytes, 0, allocPtr, structSize); return Marshal.PtrToStructure<T>(allocPtr); } finally { Marshal.FreeHGlobal(allocPtr); } }
修改GetSpawnPosition方法:
private unsafe void GetSpawnPosition(GameInfo gInfo, ref GameVector vecInfo) { byte[] buffer = new byte[sizeof(GameVector)]; if (!ReadProcessMemory(gInfo.hProc, (IntPtr)(gInfo.dwUnityPlayer + m_vecSpawn), buffer, buffer.Length, out _)) { Console.WriteLine("Couldnt read spawn cords!"); return; } vecInfo = BytesToStruct<GameVector>(buffer); }
内容的提问来源于stack exchange,提问作者Baseult
相关产品推荐
相关产品推荐

