Удалить использование unsafe кода

225
08 ноября 2021, 20:20

Возможно ли переписать метод без использование unsafe кода?

public static void ReplaceM(MethodBase src, MethodBase dest)
{
    unsafe
    {
        IntPtr srcAdr = new IntPtr(((int*)src.MethodHandle.Value.ToPointer() + 12));
        IntPtr destAdr = new IntPtr(((int*)dest.MethodHandle.Value.ToPointer() + 12));
        if (IntPtr.Size == 8)
        {
            ulong* d = (ulong*)destAdr.ToPointer();
            *d = *((ulong*)srcAdr.ToPointer());
        }
        else
        {
            uint* d = (uint*)destAdr.ToPointer();
            *d = *((uint*)srcAdr.ToPointer());
        }
    }
}
Answer 1

Можно через маршал System.Runtime.InterpropServices.Marshal

Marshal.WriteIntPtr(destAdr,Marshal.ReadIntPtr(srcAdr));

Пересмещать destAdr - это куча ненужных преобразований, маршал поддерживает смещение, поэтому, проще будет так (т.е. код ниже заменит всю процедуру)

Marshal.WriteIntPtr(dest.MethodHandle.Value,48,
 Marshal.ReadIntPtr(src.MethodHandle.Value,48));

С взятием адреса обьекта чуть сложнее (может пригодится)

 var g = GCHandle.Alloc(obj);
   g.ToIntPtr(); // Взятие адреса
 g.Free();

Последствия правда могут быть непредсказуемы, как и при unsafe.

P.S. Замена тела метода... возможно вам нужен делегат Вики делегат (переменная с ссылкой на метод)

Answer 2

Вот нашел еще вариант.

var srcAdr = src.MethodHandle.Value + 48; 
var dstAdr = dest.MethodHandle.Value + 48; 
 
var buffer = new byte[IntPtr.Size]; 
 
Marshal.Copy(srcAdr, buffer, 0, buffer.Length); 
Marshal.Copy(buffer, 0, dstAdr, buffer.Length);

READ ALSO
Как создать привязку к объекту, определённому в другом пространстве имён?

Как создать привязку к объекту, определённому в другом пространстве имён?

В ходе разработки графического интерфейса на WPF, использующего одну библиотеку классов, столкнулся с проблемой: не понимаю как привязать...

186
Настройка камеры в PixelArt игре

Настройка камеры в PixelArt игре

Я изучаю Unity3D на основе 2D pixelArt игрыЕсть задача: Правильно настроить ортографическую камеру

177
TimerCallback & Timer C#. Вызывает только один раз

TimerCallback & Timer C#. Вызывает только один раз

В конструкторе при создание класса создаю вот такой таймер

91