-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPtr.cs
More file actions
78 lines (59 loc) · 3.08 KB
/
Ptr.cs
File metadata and controls
78 lines (59 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
using System;
using System.Runtime.CompilerServices;
namespace Velctor.Utils
{
/// <summary>
/// 对原生指针的封装。便于与.Net、Unity的五花八门的指针表示互转
/// </summary>
public struct Ptr<T> where T : unmanaged
{
unsafe T* addr;
public readonly unsafe ref T Target => ref *addr;
public readonly unsafe bool IsNull => addr == null;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe Ptr(void* ptr) => addr = (T*)ptr;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe Ptr(IntPtr ptr) => addr = (T*)ptr;
/// <summary> 获取指向当前非托管值类型的指针。不要对引用类型的对象的值字段使用,因为其内存地址不固定 </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe Ptr(ref T targetObj)
{
fixed (T* p = &targetObj) {
addr = p;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe implicit operator Ptr<T>(T* nativePtr) => new(nativePtr);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe implicit operator Ptr<T>(IntPtr nativePtr) => new(nativePtr);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe implicit operator T*(Ptr<T> nativePtr) => nativePtr.addr;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe explicit operator nint(Ptr<T> v) => (nint)v.addr;
public unsafe ref T this[nint indx] => ref addr[indx];
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly unsafe Ptr<U> CastAs<U>() where U : unmanaged => new(addr);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly unsafe Span<T> AsSpan(int elemCount = 1) => new(addr, elemCount);
public override readonly unsafe string ToString() => $"0x{(UIntPtr)addr:X16}";
public static unsafe Ptr<T> operator +(Ptr<T> a, nint b) => a.addr + b;
public static unsafe Ptr<T> operator ++(Ptr<T> a) => a.addr++;
public static unsafe Ptr<T> operator --(Ptr<T> a) => a.addr--;
public static unsafe bool operator ==(Ptr<T> a, Ptr<T> b) => a.addr == b.addr;
public static unsafe bool operator !=(Ptr<T> a, Ptr<T> b) => a.addr != b.addr;
public static unsafe bool operator >(Ptr<T> a, Ptr<T> b) => a.addr > b.addr;
public static unsafe bool operator <(Ptr<T> a, Ptr<T> b) => a.addr < b.addr;
public override readonly unsafe bool Equals(object obj) => addr == ((Ptr<T>)obj).addr;
public override readonly unsafe int GetHashCode() => ((nint)addr).GetHashCode();
}
public static class Ptr
{
/// <summary> 获取指向当前非托管值类型的指针。不要对引用类型的对象的值字段使用,因为其内存地址不固定 </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Ptr<T> GetUnsafPtr<T>(ref this T target) where T : unmanaged => new(ref target);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void* AsPtr(this IntPtr intPtr) => (void*)(intPtr);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Ptr<T> AsPtr<T>(this IntPtr intPtr) where T : unmanaged => new(intPtr);
}
}