# PatcherYRpp **Repository Path**: junjacobyoung/PatcherYRpp ## Basic Information - **Project Name**: PatcherYRpp - **Description**: C# style YRpp for DynamicPatcher's Extensions. - **Primary Language**: C# - **License**: GPL-3.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-09-08 - **Last Updated**: 2022-09-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # C# Style YRpp [![license](https://www.gnu.org/graphics/gplv3-or-later.png)](https://www.gnu.org/licenses/gpl-3.0.en.html) [Pointer](Helpers/Pointer.cs) & [PointerHandle](Helpers/PointerHandle.cs) ============ It is suggested that use Pointer to replace T*. Use Pointer.Ref to access members of T. Use Pointer.Convert() if it is need to convert the pointer type. IntPtr also has this extend function. Use Pointer.AsPointer(ref obj) to get an object address. Use PointerHandle if it is need to set the pointer later(avoid GC moving). How to add class content I want? -------- First, you need a classes layout of YRPP. Every class should be writen below: ``` csharp [StructLayout(LayoutKind.Explicit, Size = struct_size)] public struct YourClass { // your function public unsafe void function() { var func = (delegate* unmanaged[Thiscall])function_address; func(ref this); } // your virtual function public unsafe void function() { var func = (delegate* unmanaged[Thiscall])Helpers.GetVirtualFunctionPointer(Pointer.AsPointer(ref this), virtual_function_index); func(ref this); } // *REMARK* // If you meet 'fastcall' function, you should use ASM.FastCallTransferStation as below. public static unsafe void function(int para) { var func = (delegate* unmanaged[Thiscall])ASM.FastCallTransferStation; func(function_address, para); } // YR's class DVC static public readonly IntPtr ArrayPointer = new IntPtr(DVC_address); static public ref DynamicVectorClass> Array { get => ref DynamicVectorClass>.GetDynamicVector(ArrayPointer); } // for xxxTypeClass static public YRPP.ABSTRACTTYPE_ARRAY ABSTRACTTYPE_ARRAY = new YRPP.ABSTRACTTYPE_ARRAY(ArrayPointer); // your member [FieldOffset(member_offset)] public TMember Member; // *REMARK* // If you meet 'bool' type, you should write as 'byte' as below. [FieldOffset(member_offset)] public byte member; public bool Member { get => Convert.ToBoolean(member); set => member = Convert.ToByte(value); } // or use simple version [FieldOffset(member_offset)] public Bool member; // *REMARK* // If you meet 'T[N]' type, you should write it as below. // Then you can access Member[i] as normal array. [FieldOffset(member_offset)] public T array_first; public Pointer Member => Pointer.AsPointer(ref array_first); // *REMARK* // you should avoid "Circular Reference" as below // which may cause Circular Reference - T1->T2->T3->T1 [FieldOffset(member_offset)] public GenericClass gT1; // the solution is use property [FieldOffset(member_offset)] public byte gT1; public ref GenericClass Member => Pointer>.AsPointer(ref gT1).Ref; // *REMARK* // If you meet string member, you should write it as below. [FieldOffset(member_offset)] public byte str_first; public AnsiStringPointer Member => Pointer.AsPointer(ref str_first); // for unicode [FieldOffset(member_offset)] public char str_first; public UniStringPointer Member => Pointer.AsPointer(ref str_first); } ``` In general, you can not write any [Non-Blittable Types](http://msdn.microsoft.com/en-us/library/75dwhxf7.aspx) in struct, or you will get many strange problem.