public unsafe void EqualityTest1() { decimal *sample = stackalloc decimal[4]; int checksum = 0; int address1 = (int)sample; Console.WriteLine("Original Address: {0:X}", address1); checksum += address1; IntPtr address2 = new IntPtr(sample); Console.WriteLine("IntPtr Address: {0:X}", address2.ToInt32()); checksum += address2.ToInt32(); DecimalPointer address3 = new DecimalPointer(address2); Console.WriteLine("DecimalPointer Address (from IntPtr): {0:X}", address3.ToInt32()); checksum += address3.ToInt32(); DecimalPointer address4 = new DecimalPointer(address1); Console.WriteLine("DecimalPointer Address (from Int32): {0:X}", address4.ToInt32()); checksum += address4.ToInt32(); int checksumDigest = checksum / 4; Assert.AreEqual(checksumDigest, address1); Assert.AreEqual(checksumDigest, address2.ToInt32()); Assert.AreEqual(checksumDigest, address3.ToInt32()); Assert.AreEqual(checksumDigest, address4.ToInt32()); }
/// <summary> /// 从元数据转换为第三方客户数据 /// </summary> /// <param name="instance">目标对象</param> /// <param name="result">分析结果</param> /// <param name="data">元数据</param> /// <param name="offset">元数据所在的偏移量</param> /// <param name="length">元数据长度</param> public override void Process(object instance, GetObjectAnalyseResult result, byte[] data, int offset, int length = 0) { if (length == 4) { result.SetValue(instance, new decimal[0]); return; } decimal[] array; unsafe { fixed(byte *pByte = &data[offset]) { int arrLength = *(int *)pByte; array = new decimal[arrLength]; if (arrLength > 10) { fixed(decimal *point = array) { Buffer.MemoryCopy((void *)new IntPtr(pByte + 4), (void *)new IntPtr((byte *)point), (uint)(Size.Decimal * arrLength), (uint)(Size.Decimal * arrLength)); //Native.Win32API.memcpy(new IntPtr((byte*)point), new IntPtr(pByte + 4), (uint)(Size.Decimal * arrLength)); } } else { decimal *point = (decimal *)(pByte + 4); for (int i = 0; i < arrLength; i++) { array[i] = *(point++); } } } } result.SetValue(instance, array); }
public unsafe void SizeOfTest1() { decimal *sample = stackalloc decimal[4]; int totalSize = 0; int ptrSize1 = Marshal.SizeOf(new DecimalPointer(sample)); Console.WriteLine("Marshal.SizeOf(new DecimalPointer(...)): {0}", ptrSize1); totalSize += ptrSize1; int ptrSize2 = Marshal.SizeOf(typeof(DecimalPointer)); Console.WriteLine("Marshal.SizeOf(typeof(DecimalPointer)): {0}", ptrSize2); totalSize += ptrSize2; int ptrSize3 = Marshal.SizeOf(IntPtr.Zero); Console.WriteLine("Marshal.SizeOf(Intptr.Zero): {0}", ptrSize3); totalSize += ptrSize3; int ptrSize4 = Marshal.SizeOf(typeof(IntPtr)); Console.WriteLine("Marshal.SizeOf(typeof(IntPtr)): {0}", ptrSize4); totalSize += ptrSize4; int ptrSize5 = Marshal.SizeOf(typeof(decimal *)); Console.WriteLine("Marshal.SizeOf(typeof(decimal*)): {0}", ptrSize5); totalSize += ptrSize5; Assert.AreEqual(totalSize, DecimalPointer.Size * 5); }
private unsafe static void DecMul10(decimal *value) { decimal d = *value; DecShiftLeft(value); DecShiftLeft(value); DecAdd(value, &d); DecShiftLeft(value); }
private unsafe static void DecShiftLeft(decimal *value) { var c0 = (value->lo & 0x80000000) > 0 ? 1 : 0; var c1 = (value->mid & 0x80000000) > 0 ? 1 : 0; value->lo <<= 1; value->mid = (uint)(value->mid << 1 | c0); value->hi = (uint)(value->hi << 1 | c1); }
/// <summary> /// Liefert den Wert (und neuen Offset) von der angegebenen Stelle im Byte-Array. /// </summary> /// <param name="Array"></param> /// <param name="Offset">Position, ab der gelesen wird.</param> unsafe static public (decimal, Int32) CopyDecimalOffset(this byte [] Array, Int32 Offset) { fixed(byte *ptr = Array) { decimal *vpdecimal = (decimal *)(ptr + Offset); return(*vpdecimal, Offset + sizeof(decimal)); } }
/// <summary> /// Liefert den Wert von der angegebenen Stelle im Byte-Array. /// </summary> /// <param name="Array"></param> /// <param name="Offset"></param> unsafe static public decimal CopyDecimal(this byte [] Array, Int32 Offset) { fixed(byte *ptr = Array) { decimal *vpdecimal = (decimal *)(ptr + Offset); return(*vpdecimal); } }
/// <summary> /// Kopiert die Werte einzeln via *ptr++. /// </summary> /// <param name="Source"></param> /// <param name="Target"></param> /// <param name="Length"></param> unsafe static public void CopyDecimals(decimal *Source, decimal *Target, int Length) { for (int i = 0; i < Length; i++) { *Target = *Source; // Source++; Target++; } }
private unsafe static void DecAddInt32(decimal *value, uint i) { if (D32AddCarry(&value->lo, i)) { if (D32AddCarry(&value->mid, 1)) { D32AddCarry(&value->hi, 1); } } }
/// <summary> /// Kopiert den Wert an die angegebene Stelle in das Byte-Array. /// </summary> /// <param name="Array"></param> /// <param name="Offset">Position, ab der geschrieben wird. Erhöht sich um die Anzhal der gelesenen Bytes!</param> /// <param name="Value"></param> unsafe static public void CopyDecimal(this byte [] Array, ref Int32 Offset, decimal Value) { fixed(byte *ptr = Array) { decimal *vp = (decimal *)(ptr + Offset); *vp = Value; Offset += sizeof(decimal); } }
/// <summary> /// Kopiert den Wert an die angegebene Stelle in das Byte-Array und liefert den neuen Offset zurück. /// </summary> /// <param name="Array"></param> /// <param name="Offset"></param> /// <param name="Value"></param> /// <returns>Liefert den neuen Offset.</returns> unsafe static public Int32 CopyDecimal(this byte [] Array, Int32 Offset, decimal Value) { fixed(byte *ptr = Array) { decimal *vp = (decimal *)(ptr + Offset); *vp = Value; } return(Offset + sizeof(decimal)); }
private unsafe void LLt(decimal[,] value) { n = value.GetLength(0); L = new decimal[n, n]; D = new decimal[n]; for (int i = 0; i < D.Length; i++) { D[i] = 1; } robust = false; decimal[,] a = value; this.positiveDefinite = true; this.symmetric = true; fixed(decimal *ptrL = L) { for (int j = 0; j < n; j++) { decimal *Lrowj = ptrL + j * n; decimal d = 0; for (int k = 0; k < j; k++) { decimal *Lrowk = ptrL + k * n; decimal s = 0; for (int i = 0; i < k; i++) { s += Lrowk[i] * Lrowj[i]; } Lrowj[k] = s = (a[j, k] - s) / Lrowk[k]; d += s * s; this.symmetric = this.symmetric & (a[k, j] == a[j, k]); } d = a[j, j] - d; // Use a tolerance for positive-definiteness this.positiveDefinite &= (d > (decimal)1e-14 * Math.Abs(a[j, j])); Lrowj[j] = (decimal)System.Math.Sqrt((double)System.Math.Max(d, 0)); for (int k = j + 1; k < n; k++) { Lrowj[k] = 0; } } } }
void handle() { //也可以标记代码块unsafe unsafe { //注意 是在stack上分配的内存 和C++不同(分配的内存没有初始化) decimal *pDecimals = stackalloc decimal[10]; *(pDecimals) = 0; *(pDecimals + 1) = 1; pDecimals[2] = 2; // 这里等价于 *(pDecimals + 2) = 2; *pX += 10; } }
/// <summary> /// Liefert den Wert von der angegebenen Stelle im Byte-Array. /// </summary> /// <param name="Array"></param> /// <param name="Offset">Position, ab der geschrieben wird. Erhöht sich um die Anzhal der gelesenen Bytes!</param> unsafe static public decimal CopyDecimal(this byte [] Array, ref Int32 Offset) { try { fixed(byte *ptr = Array) { decimal *vpdecimal = (decimal *)(ptr + Offset); return(*vpdecimal); } } finally { Offset += sizeof(decimal); } }
public override bool Equals(object obj) { decimal *pointer = null; if (obj is IntPtr) { pointer = (decimal *)(IntPtr)obj; } else if (obj is DecimalPointer) { pointer = (decimal *)(DecimalPointer)obj; } return(pointer == this.internalPointer); }
private unsafe static void DecAdd(decimal *value, decimal *d) { if (D32AddCarry(&value->lo, (uint)d->lo)) { if (D32AddCarry(&value->mid, 1)) { D32AddCarry(&value->hi, 1); } } if (D32AddCarry(&value->mid, (uint)d->mid)) { D32AddCarry(&value->hi, 1); } D32AddCarry(&value->hi, (uint)d->hi); }
public unsafe void AddressTest1() { decimal * sample = stackalloc decimal[4]; DecimalPointer a = new DecimalPointer(sample); DecimalPointer b = (a + 1); Console.WriteLine("Address offset: {0}", b.ToInt32() - a.ToInt32()); Assert.AreEqual(sizeof(decimal), b.ToInt32() - a.ToInt32()); Assert.False(Object.ReferenceEquals(a, b)); // xPlatform's typed pointers are value type. DecimalPointer c = new DecimalPointer(sample + 1); DecimalPointer d = (++c); Console.WriteLine("Address offset: {0}", d.ToInt32() - c.ToInt32()); Assert.AreEqual(0, d.ToInt32() - c.ToInt32()); Assert.False(Object.ReferenceEquals(c, d)); }
/// <summary> /// 写入一个指定类型的值 /// </summary> /// <param name="value">指定类型的值</param> public void WriteDecimal(decimal *value) { decimal * pValue = value; IMemorySegment segment = GetSegment(_currentIndex); uint remainingSize; if (segment.EnsureSize(Size.Decimal, out remainingSize)) { segment.WriteDecimal(pValue); } else { uint trueRemainingSize = Size.Decimal; if (remainingSize > 0U) { segment.WriteMemory((IntPtr)pValue, remainingSize); trueRemainingSize -= remainingSize; } segment = GetSegment(++_currentIndex); segment.WriteMemory((IntPtr)((byte *)pValue + remainingSize), trueRemainingSize); } }
public unsafe void StackallocTest3() { const int bufferSize = 4; decimal * sample = stackalloc decimal[bufferSize]; DecimalPointer pointer = new DecimalPointer(sample); decimal[] results = new decimal[bufferSize]; for (int i = 0; i < bufferSize; i++) { results[i] = *(sample + i) = GenerateRandomNumber(); } // Pointer conversion test for (int i = 0; i < bufferSize; i++) { object x = results[i]; object y = *(decimal *)(pointer + i); Console.WriteLine("[{0}] <Left: {1}> {2} <Right: {3}>", i, x, x.Equals(y) ? "==" : "<>", y); Assert.AreEqual(x, y); } }
public unsafe void StackallocTest4() { const int bufferSize = 4; decimal * sample = stackalloc decimal[bufferSize]; DecimalPointer pointer = new DecimalPointer(sample); decimal[] results = new decimal[bufferSize]; // SetData method for (int i = 0; i < bufferSize; i++) { pointer.SetData(results[i] = GenerateRandomNumber(), i); } // GetData method for (int i = 0; i < bufferSize; i++) { object x = results[i]; object y = pointer.GetData(i); Console.WriteLine("[{0}] <Left: {1}> {2} <Right: {3}>", i, x, x.Equals(y) ? "==" : "<>", y); Assert.AreEqual(x, y); } }
public unsafe void SizeOfTest2() { decimal *sample = stackalloc decimal[4]; int totalSize = 0; int ptrSize1 = sizeof(DecimalPointer); Console.WriteLine("sizeof(DecimalPointer): {0}", ptrSize1); totalSize += ptrSize1; int ptrSize2 = sizeof(IntPtr); Console.WriteLine("sizeof(IntPtr): {0}", ptrSize2); totalSize += ptrSize2; int ptrSize3 = sizeof(decimal *); Console.WriteLine("sizeof(decimal*): {0}", ptrSize3); totalSize += ptrSize3; Assert.AreEqual(totalSize, DecimalPointer.Size * 3); }
public unsafe void StackallocTest5() { const int bufferSize = 4; decimal * sample = stackalloc decimal[bufferSize]; DecimalPointer pointer = new DecimalPointer(sample); decimal[] results = new decimal[bufferSize]; // Indexer based memory writing for (int i = 0; i < bufferSize; i++) { results[i] = pointer[i] = GenerateRandomNumber(); } // Indexer based memory navigation for (int i = 0; i < bufferSize; i++) { object x = results[i]; object y = pointer[i]; Console.WriteLine("[{0}] <Left: {1}> {2} <Right: {3}>", i, x, x.Equals(y) ? "==" : "<>", y); Assert.AreEqual(x, y); } }
/// <summary> /// 元数据转换成第三方数据 /// </summary> /// <param name="metadataObject">元数据集合</param> /// <param name="id">属性对应key</param> /// <param name="data">属性对应byte数组</param> /// <param name="offsetStart">属性在数组中的偏移值</param> /// <param name="length">属性在byte数组中的长度</param> /// <exception cref="ArgumentNullException">参数不能为空</exception> public unsafe void DataProcessor(MetadataContainer metadataObject, byte id, byte[] data, int offsetStart, uint length) { if (metadataObject == null) { throw new ArgumentNullException("metadataObject"); } if (length == 0) { metadataObject.SetAttribute(id, new DecimalArrayValueStored(new decimal[0])); return; } decimal[] array = new decimal[length / Size.Decimal]; fixed(byte *pByte = (&data[offsetStart])) { decimal *pData = (decimal *)pByte; for (int j = 0; j < array.Length; j++) { array[j] = *pData++; } } metadataObject.SetAttribute(id, new DecimalArrayValueStored(array)); }
private unsafe string EncodeObject(object data, MofField *mofField, char *ptr, ref uint offSet, byte *ptrArgInfo) { if (data == null) { if (ptrArgInfo != null) { *ptrArgInfo = (byte)0; //NULL type, WIN64 Changes *(ushort *)(ptrArgInfo + 1) = (ushort)0; } mofField->DataLength = 0; mofField->DataPointer = (void *)null; //WIN64 Changes (?) return(null); } // if the data is an enum we'll convert it to its underlying type Type dataType = data.GetType(); if (dataType.IsEnum) { data = Convert.ChangeType(data, Enum.GetUnderlyingType(dataType), CultureInfo.InvariantCulture); } string sRet = data as string; if (sRet != null) { if (ptrArgInfo != null) { *ptrArgInfo = (byte)2; //WIN64 Changes *(ushort *)(ptrArgInfo + 1) = (ushort)(sRet.Length < 65535 ? sRet.Length : 65535); //WIN64 Changes } else { // TraceEvent path. Need counted strings. mofField->DataLength = sizeof(ushort); ushort *ushortptr = (ushort *)ptr; * ushortptr = (ushort)(sRet.Length * 2 < 65535 ? sRet.Length * 2 : 65535); mofField->DataPointer = (void *)ushortptr; offSet += sizeof(ushort); } return(sRet); } if (data is sbyte) { mofField->DataLength = sizeof(sbyte); if (ptrArgInfo != null) { *ptrArgInfo = (byte)3; //WIN64 Changes } sbyte *sbyteptr = (sbyte *)ptr; * sbyteptr = (sbyte)data; //WIN64 Changes mofField->DataPointer = (void *)sbyteptr; offSet += sizeof(sbyte); } else if (data is byte) { mofField->DataLength = sizeof(byte); if (ptrArgInfo != null) { *ptrArgInfo = (byte)4; //WIN64 Changes } byte *byteptr = (byte *)ptr; * byteptr = (byte)data; //WIN64 Changes mofField->DataPointer = (void *)byteptr; offSet += sizeof(byte); } else if (data is short) { mofField->DataLength = sizeof(short); if (ptrArgInfo != null) { *ptrArgInfo = (byte)5; //WIN64 Changes } short *shortptr = (short *)ptr; * shortptr = (short)data; //WIN64 Changes mofField->DataPointer = (void *)shortptr; offSet += sizeof(short); } else if (data is ushort) { mofField->DataLength = sizeof(ushort); if (ptrArgInfo != null) { *ptrArgInfo = (byte)6; //WIN64 Changes } ushort *ushortptr = (ushort *)ptr; * ushortptr = (ushort)data; //WIN64 Changes mofField->DataPointer = (void *)ushortptr; offSet += sizeof(ushort); } else if (data is int) { mofField->DataLength = sizeof(int); if (ptrArgInfo != null) { *ptrArgInfo = (byte)7; //WIN64 Changes } int *intptr = (int *)ptr; * intptr = (int)data; //WIN64 Changes mofField->DataPointer = (void *)intptr; offSet += sizeof(int); } else if (data is uint) { mofField->DataLength = sizeof(uint); if (ptrArgInfo != null) { *ptrArgInfo = (byte)8; //WIN64 Changes } uint *uintptr = (uint *)ptr; * uintptr = (uint)data; //WIN64 Changes mofField->DataPointer = (void *)uintptr; offSet += sizeof(uint); } else if (data is long) { mofField->DataLength = sizeof(long); if (ptrArgInfo != null) { *ptrArgInfo = (byte)9; //WIN64 Changes } long *longptr = (long *)ptr; * longptr = (long)data; //WIN64 Changes mofField->DataPointer = (void *)longptr; offSet += sizeof(long); } else if (data is ulong) { mofField->DataLength = sizeof(ulong); if (ptrArgInfo != null) { *ptrArgInfo = (byte)10; //WIN64 Changes } ulong *ulongptr = (ulong *)ptr; * ulongptr = (ulong)data; //WIN64 Changes mofField->DataPointer = (void *)ulongptr; offSet += sizeof(ulong); } else if (data is char) { mofField->DataLength = sizeof(char); if (ptrArgInfo != null) { *ptrArgInfo = (byte)11; //WIN64 Changes } char *charptr = (char *)ptr; * charptr = (char)data; //WIN64 Changes mofField->DataPointer = (void *)charptr; offSet += sizeof(char); } else if (data is float) { mofField->DataLength = sizeof(float); if (ptrArgInfo != null) { *ptrArgInfo = (byte)12; //WIN64 Changes } float *floatptr = (float *)ptr; * floatptr = (float)data; //WIN64 Changes mofField->DataPointer = (void *)floatptr; offSet += sizeof(float); } else if (data is double) { mofField->DataLength = sizeof(double); if (ptrArgInfo != null) { *ptrArgInfo = (byte)13; //WIN64 Changes } double *doubleptr = (double *)ptr; * doubleptr = (double)data; //WIN64 Changes mofField->DataPointer = (void *)doubleptr; offSet += sizeof(double); } else if (data is bool) { mofField->DataLength = sizeof(bool); if (ptrArgInfo != null) { *ptrArgInfo = (byte)14; //WIN64 Changes } bool *boolptr = (bool *)ptr; * boolptr = (bool)data; //WIN64 Changes mofField->DataPointer = (void *)boolptr; offSet += sizeof(bool); } else if (data is decimal) { mofField->DataLength = (uint)sizeof(decimal); if (ptrArgInfo != null) { *ptrArgInfo = (byte)15; //WIN64 Changes } decimal *decimalptr = (decimal *)ptr; * decimalptr = (decimal)data; //WIN64 Changes mofField->DataPointer = (void *)decimalptr; offSet += (uint)sizeof(decimal); } else { //To our eyes, everything else is a just a string sRet = data.ToString(); if (ptrArgInfo != null) { *ptrArgInfo = (byte)2; //WIN64 Changes *(ushort *)(ptrArgInfo + 1) = (ushort)(sRet.Length < 65535 ? sRet.Length : 65535); //WIN64 Changes } else { // TraceEvent path. Need counted strings. mofField->DataLength = sizeof(ushort); ushort *ushortptr = (ushort *)ptr; * ushortptr = (ushort)(sRet.Length * 2 < 65535 ? sRet.Length * 2 : 65535); mofField->DataPointer = (void *)ushortptr; offSet += sizeof(ushort); } return(sRet); } if (ptrArgInfo != null) { *(ushort *)(ptrArgInfo + 1) = (ushort)(mofField->DataLength); //WIN64 Changes (?) } return(sRet); }
static unsafe string EncodeObject(ref object data, UnsafeNativeMethods.EventData *dataDescriptor, byte *dataBuffer) { dataDescriptor->Reserved = 0; string sRet = data as string; if (sRet != null) { dataDescriptor->Size = (uint)((sRet.Length + 1) * 2); return(sRet); } if (data is IntPtr) { dataDescriptor->Size = (uint)sizeof(IntPtr); IntPtr *intptrPtr = (IntPtr *)dataBuffer; * intptrPtr = (IntPtr)data; dataDescriptor->DataPointer = (ulong)intptrPtr; } else if (data is int) { dataDescriptor->Size = (uint)sizeof(int); int *intptrPtr = (int *)dataBuffer; * intptrPtr = (int)data; dataDescriptor->DataPointer = (ulong)intptrPtr; } else if (data is long) { dataDescriptor->Size = (uint)sizeof(long); long *longptr = (long *)dataBuffer; * longptr = (long)data; dataDescriptor->DataPointer = (ulong)longptr; } else if (data is uint) { dataDescriptor->Size = (uint)sizeof(uint); uint *uintptr = (uint *)dataBuffer; * uintptr = (uint)data; dataDescriptor->DataPointer = (ulong)uintptr; } else if (data is UInt64) { dataDescriptor->Size = (uint)sizeof(ulong); UInt64 *ulongptr = (ulong *)dataBuffer; * ulongptr = (ulong)data; dataDescriptor->DataPointer = (ulong)ulongptr; } else if (data is char) { dataDescriptor->Size = (uint)sizeof(char); char *charptr = (char *)dataBuffer; * charptr = (char)data; dataDescriptor->DataPointer = (ulong)charptr; } else if (data is byte) { dataDescriptor->Size = (uint)sizeof(byte); byte *byteptr = (byte *)dataBuffer; * byteptr = (byte)data; dataDescriptor->DataPointer = (ulong)byteptr; } else if (data is short) { dataDescriptor->Size = (uint)sizeof(short); short *shortptr = (short *)dataBuffer; * shortptr = (short)data; dataDescriptor->DataPointer = (ulong)shortptr; } else if (data is sbyte) { dataDescriptor->Size = (uint)sizeof(sbyte); sbyte *sbyteptr = (sbyte *)dataBuffer; * sbyteptr = (sbyte)data; dataDescriptor->DataPointer = (ulong)sbyteptr; } else if (data is ushort) { dataDescriptor->Size = (uint)sizeof(ushort); ushort *ushortptr = (ushort *)dataBuffer; * ushortptr = (ushort)data; dataDescriptor->DataPointer = (ulong)ushortptr; } else if (data is float) { dataDescriptor->Size = (uint)sizeof(float); float *floatptr = (float *)dataBuffer; * floatptr = (float)data; dataDescriptor->DataPointer = (ulong)floatptr; } else if (data is double) { dataDescriptor->Size = (uint)sizeof(double); double *doubleptr = (double *)dataBuffer; * doubleptr = (double)data; dataDescriptor->DataPointer = (ulong)doubleptr; } else if (data is bool) { dataDescriptor->Size = (uint)sizeof(bool); bool *boolptr = (bool *)dataBuffer; * boolptr = (bool)data; dataDescriptor->DataPointer = (ulong)boolptr; } else if (data is Guid) { dataDescriptor->Size = (uint)sizeof(Guid); Guid *guidptr = (Guid *)dataBuffer; * guidptr = (Guid)data; dataDescriptor->DataPointer = (ulong)guidptr; } else if (data is decimal) { dataDescriptor->Size = (uint)sizeof(decimal); decimal *decimalptr = (decimal *)dataBuffer; * decimalptr = (decimal)data; dataDescriptor->DataPointer = (ulong)decimalptr; } else if (data is Boolean) { dataDescriptor->Size = (uint)sizeof(Boolean); Boolean *booleanptr = (Boolean *)dataBuffer; * booleanptr = (Boolean)data; dataDescriptor->DataPointer = (ulong)booleanptr; } else { // Everything else is a just a string sRet = data.ToString(); dataDescriptor->Size = (uint)((sRet.Length + 1) * 2); return(sRet); } return(null); }
private static unsafe string EncodeObject(ref object data, EventData *dataDescriptor, byte *dataBuffer) /*++ * * Routine Description: * * This routine is used by WriteEvent to unbox the object type and * to fill the passed in ETW data descriptor. * * Arguments: * * data - argument to be decoded * * dataDescriptor - pointer to the descriptor to be filled * * dataBuffer - storage buffer for storing user data, needed because cant get the address of the object * * Return Value: * * null if the object is a basic type other than string. String otherwise * * --*/ { dataDescriptor->Reserved = 0; string sRet = data as string; if (sRet != null) { dataDescriptor->Size = (uint)((sRet.Length + 1) * 2); return(sRet); } if (data == null) { dataDescriptor->Size = 0; dataDescriptor->DataPointer = 0; } else if (data is IntPtr) { dataDescriptor->Size = (uint)sizeof(IntPtr); IntPtr *intptrPtr = (IntPtr *)dataBuffer; * intptrPtr = (IntPtr)data; dataDescriptor->DataPointer = (ulong)intptrPtr; } else if (data is int) { dataDescriptor->Size = (uint)sizeof(int); int *intptrPtr = (int *)dataBuffer; * intptrPtr = (int)data; dataDescriptor->DataPointer = (ulong)intptrPtr; } else if (data is long) { dataDescriptor->Size = (uint)sizeof(long); long *longptr = (long *)dataBuffer; * longptr = (long)data; dataDescriptor->DataPointer = (ulong)longptr; } else if (data is uint) { dataDescriptor->Size = (uint)sizeof(uint); uint *uintptr = (uint *)dataBuffer; * uintptr = (uint)data; dataDescriptor->DataPointer = (ulong)uintptr; } else if (data is ulong) { dataDescriptor->Size = (uint)sizeof(ulong); ulong *ulongptr = (ulong *)dataBuffer; * ulongptr = (ulong)data; dataDescriptor->DataPointer = (ulong)ulongptr; } else if (data is char) { dataDescriptor->Size = (uint)sizeof(char); char *charptr = (char *)dataBuffer; * charptr = (char)data; dataDescriptor->DataPointer = (ulong)charptr; } else if (data is byte) { dataDescriptor->Size = (uint)sizeof(byte); byte *byteptr = (byte *)dataBuffer; * byteptr = (byte)data; dataDescriptor->DataPointer = (ulong)byteptr; } else if (data is short) { dataDescriptor->Size = (uint)sizeof(short); short *shortptr = (short *)dataBuffer; * shortptr = (short)data; dataDescriptor->DataPointer = (ulong)shortptr; } else if (data is sbyte) { dataDescriptor->Size = (uint)sizeof(sbyte); sbyte *sbyteptr = (sbyte *)dataBuffer; * sbyteptr = (sbyte)data; dataDescriptor->DataPointer = (ulong)sbyteptr; } else if (data is ushort) { dataDescriptor->Size = (uint)sizeof(ushort); ushort *ushortptr = (ushort *)dataBuffer; * ushortptr = (ushort)data; dataDescriptor->DataPointer = (ulong)ushortptr; } else if (data is float) { dataDescriptor->Size = (uint)sizeof(float); float *floatptr = (float *)dataBuffer; * floatptr = (float)data; dataDescriptor->DataPointer = (ulong)floatptr; } else if (data is double) { dataDescriptor->Size = (uint)sizeof(double); double *doubleptr = (double *)dataBuffer; * doubleptr = (double)data; dataDescriptor->DataPointer = (ulong)doubleptr; } else if (data is bool) { dataDescriptor->Size = (uint)sizeof(bool); bool *boolptr = (bool *)dataBuffer; * boolptr = (bool)data; dataDescriptor->DataPointer = (ulong)boolptr; } else if (data is Guid) { dataDescriptor->Size = (uint)sizeof(Guid); Guid *guidptr = (Guid *)dataBuffer; * guidptr = (Guid)data; dataDescriptor->DataPointer = (ulong)guidptr; } else if (data is decimal) { dataDescriptor->Size = (uint)sizeof(decimal); decimal *decimalptr = (decimal *)dataBuffer; * decimalptr = (decimal)data; dataDescriptor->DataPointer = (ulong)decimalptr; } else { // To our eyes, everything else is a just a string sRet = data.ToString(); dataDescriptor->Size = (uint)((sRet.Length + 1) * 2); return(sRet); } return(null); }
private static unsafe string EncodeObject(ref object data, UnsafeNativeMethods.EventData *dataDescriptor, byte *dataBuffer) { (*dataDescriptor).Reserved = 0; string str = data as string; if (str != null) { (*dataDescriptor).Size = (uint)((str.Length + 1) * 2); return(str); } if (data is IntPtr) { (*dataDescriptor).Size = sizeof(IntPtr); IntPtr *intPtrPointer = (IntPtr *)dataBuffer; * intPtrPointer = (IntPtr)data; (*dataDescriptor).DataPointer = (ulong)intPtrPointer; } else if (data is int) { (*dataDescriptor).Size = 4; int *numPointer = (int *)dataBuffer; * numPointer = (int)data; (*dataDescriptor).DataPointer = (ulong)numPointer; } else if (data is long) { (*dataDescriptor).Size = 8; long *numPointer1 = (long *)dataBuffer; * numPointer1 = (long)data; (*dataDescriptor).DataPointer = (ulong)numPointer1; } else if (data is uint) { (*dataDescriptor).Size = 4; uint *numPointer2 = (uint *)dataBuffer; * numPointer2 = (uint)data; (*dataDescriptor).DataPointer = (ulong)numPointer2; } else if (data is ulong) { (*dataDescriptor).Size = 8; ulong *numPointer3 = (ulong *)dataBuffer; * numPointer3 = (ulong)data; (*dataDescriptor).DataPointer = (ulong)numPointer3; } else if (data is char) { (*dataDescriptor).Size = 2; char *chrPointer = (char *)dataBuffer; * chrPointer = (char)data; (*dataDescriptor).DataPointer = (ulong)chrPointer; } else if (data is byte) { (*dataDescriptor).Size = 1; byte *numPointer4 = dataBuffer; * numPointer4 = (byte)data; (*dataDescriptor).DataPointer = (ulong)numPointer4; } else if (data is short) { (*dataDescriptor).Size = 2; short *numPointer5 = (short *)dataBuffer; * numPointer5 = (short)data; (*dataDescriptor).DataPointer = (ulong)numPointer5; } else if (data is sbyte) { (*dataDescriptor).Size = 1; sbyte *numPointer6 = (sbyte *)dataBuffer; * numPointer6 = (sbyte)data; (*dataDescriptor).DataPointer = (ulong)numPointer6; } else if (data is ushort) { (*dataDescriptor).Size = 2; ushort *numPointer7 = (ushort *)dataBuffer; * numPointer7 = (ushort)data; (*dataDescriptor).DataPointer = (ulong)numPointer7; } else if (data is float) { (*dataDescriptor).Size = 4; float *singlePointer = (float *)dataBuffer; * singlePointer = (float)data; (*dataDescriptor).DataPointer = (ulong)singlePointer; } else if (data is double) { (*dataDescriptor).Size = 8; double *numPointer8 = (double *)dataBuffer; * numPointer8 = (double)data; (*dataDescriptor).DataPointer = (ulong)numPointer8; } else if (data is bool) { (*dataDescriptor).Size = 1; bool *flagPointer = (bool *)dataBuffer; * flagPointer = (bool)data; (*dataDescriptor).DataPointer = (ulong)flagPointer; } else if (data is Guid) { (*dataDescriptor).Size = sizeof(Guid); Guid *guidPointer = (Guid *)dataBuffer; * guidPointer = (Guid)data; (*dataDescriptor).DataPointer = (ulong)guidPointer; } else if (!(data is decimal)) { if (!(data is bool)) { str = data.ToString(); (*dataDescriptor).Size = (uint)((str.Length + 1) * 2); return(str); } (*dataDescriptor).Size = 1; bool *flagPointer1 = (bool *)dataBuffer; * flagPointer1 = (bool)data; (*dataDescriptor).DataPointer = (ulong)flagPointer1; } else { (*dataDescriptor).Size = 16; decimal *numPointer9 = (decimal *)dataBuffer; * numPointer9 = (decimal)data; (*dataDescriptor).DataPointer = (ulong)numPointer9; } return(null); }
/// <summary> /// Constructs a new LU decomposition. /// </summary> /// <param name="value">The matrix A to be decomposed.</param> /// <param name="transpose">True if the decomposition should be performed on /// the transpose of A rather than A itself, false otherwise. Default is false.</param> /// <param name="inPlace">True if the decomposition should be performed over the /// <paramref name="value"/> matrix rather than on a copy of it. If true, the /// matrix will be destroyed during the decomposition. Default is false.</param> /// public LuDecompositionD(decimal[,] value, bool transpose, bool inPlace) { if (value == null) { throw new ArgumentNullException("value", "Matrix cannot be null."); } if (transpose) { this.lu = value.Transpose(inPlace); } else { this.lu = inPlace ? value : (decimal[, ])value.Clone(); } this.rows = lu.GetLength(0); this.cols = lu.GetLength(1); this.pivotSign = 1; this.pivotVector = new int[rows]; for (int i = 0; i < rows; i++) { pivotVector[i] = i; } var LUcolj = new decimal[rows]; unsafe { fixed(decimal *LU = lu) { // Outer loop. for (int j = 0; j < cols; j++) { // Make a copy of the j-th column to localize references. for (int i = 0; i < rows; i++) { LUcolj[i] = lu[i, j]; } // Apply previous transformations. for (int i = 0; i < rows; i++) { decimal s = 0; // Most of the time is spent in // the following dot product: int kmax = Math.Min(i, j); decimal *LUrowi = &LU[i * cols]; for (int k = 0; k < kmax; k++) { s += LUrowi[k] * LUcolj[k]; } LUrowi[j] = LUcolj[i] -= s; } // Find pivot and exchange if necessary. int p = j; for (int i = j + 1; i < rows; i++) { if (Math.Abs(LUcolj[i]) > Math.Abs(LUcolj[p])) { p = i; } } if (p != j) { for (int k = 0; k < cols; k++) { var t = lu[p, k]; lu[p, k] = lu[j, k]; lu[j, k] = t; } int v = pivotVector[p]; pivotVector[p] = pivotVector[j]; pivotVector[j] = v; pivotSign = -pivotSign; } // Compute multipliers. if (j < rows && lu[j, j] != 0) { for (int i = j + 1; i < rows; i++) { lu[i, j] /= lu[j, j]; } } } } } }
public static void TypicalScene() { const int count = 1000000; long startTick = 0; long interval, interval2; // 测试float类型 { var floatArray = new UnmanagedArray <float>(count); startTick = DateTime.Now.Ticks; for (int i = 0; i < count; i++) { floatArray[i] = i; } for (int i = 0; i < count; i++) { var item = floatArray[i]; if (item != i) { throw new Exception(); } } interval = DateTime.Now.Ticks - startTick; unsafe { startTick = DateTime.Now.Ticks; float *header = (float *)floatArray.FirstElement(); float *last = (float *)floatArray.LastElement(); float *tailAddress = (float *)floatArray.TailAddress(); int value = 0; for (float *ptr = header; ptr <= last /*or: ptr < tailAddress*/; ptr++) { *ptr = value++; } int i = 0; for (float *ptr = header; ptr <= last /*or: ptr < tailAddress*/; ptr++, i++) { var item = *ptr; if (item != i) { throw new Exception(); } } interval2 = DateTime.Now.Ticks - startTick; } Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2); } // 测试decimal类型 { var decimalArray = new UnmanagedArray <decimal>(count); startTick = DateTime.Now.Ticks; for (int i = 0; i < count; i++) { decimalArray[i] = i; } for (int i = 0; i < count; i++) { var item = decimalArray[i]; if (item != i) { throw new Exception(); } } interval = DateTime.Now.Ticks - startTick; unsafe { startTick = DateTime.Now.Ticks; decimal *header = (decimal *)decimalArray.FirstElement(); decimal *last = (decimal *)decimalArray.LastElement(); decimal *tailAddress = (decimal *)decimalArray.TailAddress(); int value = 0; for (decimal *ptr = header; ptr <= last /*or: ptr < tailAddress*/; ptr++) { *ptr = value++; } int i = 0; for (decimal *ptr = header; ptr <= last /*or: ptr < tailAddress*/; ptr++, i++) { var item = *ptr; if (item != i) { throw new Exception(); } } interval2 = DateTime.Now.Ticks - startTick; } Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2); } // 测试int类型 { var intArray = new UnmanagedArray <int>(count); startTick = DateTime.Now.Ticks; for (int i = 0; i < count; i++) { intArray[i] = i; } for (int i = 0; i < count; i++) { var item = intArray[i]; if (item != i) { throw new Exception(); } } interval = DateTime.Now.Ticks - startTick; unsafe { startTick = DateTime.Now.Ticks; int *header = (int *)intArray.FirstElement(); int *last = (int *)intArray.LastElement(); int *tailAddress = (int *)intArray.TailAddress(); int value = 0; for (int *ptr = header; ptr <= last /*or: ptr < tailAddress*/; ptr++) { *ptr = value++; } int i = 0; for (int *ptr = header; ptr <= last /*or: ptr < tailAddress*/; ptr++, i++) { var item = *ptr; if (item != i) { throw new Exception(); } } interval2 = DateTime.Now.Ticks - startTick; } Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2); } // 测试bool类型 { var boolArray = new UnmanagedArray <bool>(count); startTick = DateTime.Now.Ticks; for (int i = 0; i < count; i++) { boolArray[i] = i % 2 == 0; } for (int i = 0; i < count; i++) { var item = boolArray[i]; if (item != (i % 2 == 0)) { throw new Exception(); } } interval = DateTime.Now.Ticks - startTick; unsafe { startTick = DateTime.Now.Ticks; bool *header = (bool *)boolArray.FirstElement(); bool *last = (bool *)boolArray.LastElement(); bool *tailAddress = (bool *)boolArray.TailAddress(); int value = 0; for (bool *ptr = header; ptr <= last /*or: ptr < tailAddress*/; ptr++) { *ptr = (value % 2 == 0); value++; } int i = 0; for (bool *ptr = header; ptr <= last /*or: ptr < tailAddress*/; ptr++, i++) { var item = *ptr; if (item != (i % 2 == 0)) { throw new Exception(); } } interval2 = DateTime.Now.Ticks - startTick; } Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2); } // 测试vec3类型 { var vec3Array = new UnmanagedArray <vec3>(count); startTick = DateTime.Now.Ticks; for (int i = 0; i < count; i++) { vec3Array[i] = new vec3(i * 3 + 0, i * 3 + 1, i * 3 + 2); } for (int i = 0; i < count; i++) { var item = vec3Array[i]; var old = new vec3(i * 3 + 0, i * 3 + 1, i * 3 + 2); if (item.x != old.x || item.y != old.y || item.z != old.z) { throw new Exception(); } } interval = DateTime.Now.Ticks - startTick; unsafe { startTick = DateTime.Now.Ticks; vec3 *header = (vec3 *)vec3Array.FirstElement(); vec3 *last = (vec3 *)vec3Array.LastElement(); vec3 *tailAddress = (vec3 *)vec3Array.TailAddress(); int i = 0; for (vec3 *ptr = header; ptr <= last /*or: ptr < tailAddress*/; ptr++) { *ptr = new vec3(i * 3 + 0, i * 3 + 1, i * 3 + 2); i++; } i = 0; for (vec3 *ptr = header; ptr <= last /*or: ptr < tailAddress*/; ptr++, i++) { var item = *ptr; var old = new vec3(i * 3 + 0, i * 3 + 1, i * 3 + 2); if (item.x != old.x || item.y != old.y || item.z != old.z) { throw new Exception(); } } interval2 = DateTime.Now.Ticks - startTick; } Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2); } // 测试mat4类型 { var vec3Array = new UnmanagedArray <mat4>(count); startTick = DateTime.Now.Ticks; for (int i = 0; i < count; i++) { vec3Array[i] = new mat4(new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3)); } for (int i = 0; i < count; i++) { var item = vec3Array[i]; var old = new mat4(new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3)); for (int col = 0; col < 4; col++) { for (int row = 0; row < 4; row++) { if (item[col][row] != old[col][row]) { throw new Exception(); } } } } interval = DateTime.Now.Ticks - startTick; unsafe { startTick = DateTime.Now.Ticks; mat4 *header = (mat4 *)vec3Array.FirstElement(); mat4 *last = (mat4 *)vec3Array.LastElement(); mat4 *tailAddress = (mat4 *)vec3Array.TailAddress(); int i = 0; for (mat4 *ptr = header; ptr <= last /*or: ptr < tailAddress*/; ptr++) { *ptr = new mat4(new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3)); i++; } i = 0; for (mat4 *ptr = header; ptr <= last /*or: ptr < tailAddress*/; ptr++, i++) { var item = *ptr; var old = new mat4(new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3)); for (int col = 0; col < 4; col++) { for (int row = 0; row < 4; row++) { if (item[col][row] != old[col][row]) { throw new Exception(); } } } } interval2 = DateTime.Now.Ticks - startTick; } Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2); } // 立即释放所有非托管数组占用的内存,任何之前创建的UnmanagedBase数组都不再可用了。 UnmanagedArray <int> .FreeAll(); }
private static unsafe string EncodeObject(ref object data, EventData *dataDescriptor, byte *dataBuffer) /*++ * * Routine Description: * * This routine is used by WriteEvent to unbox the object type and * to fill the passed in ETW data descriptor. * * Arguments: * * data - argument to be decoded * * dataDescriptor - pointer to the descriptor to be filled * * dataBuffer - storage buffer for storing user data, needed because cant get the address of the object * * Return Value: * * null if the object is a basic type other than string. String otherwise * * --*/ { Again: dataDescriptor->Reserved = 0; string sRet = data as string; if (sRet != null) { dataDescriptor->Size = (uint)((sRet.Length + 1) * 2); return(sRet); } if (data is IntPtr) { dataDescriptor->Size = (uint)sizeof(IntPtr); IntPtr *intptrPtr = (IntPtr *)dataBuffer; * intptrPtr = (IntPtr)data; dataDescriptor->Ptr = (ulong)intptrPtr; } else if (data is int) { dataDescriptor->Size = (uint)sizeof(int); int *intptr = (int *)dataBuffer; * intptr = (int)data; dataDescriptor->Ptr = (ulong)intptr; } else if (data is long) { dataDescriptor->Size = (uint)sizeof(long); long *longptr = (long *)dataBuffer; * longptr = (long)data; dataDescriptor->Ptr = (ulong)longptr; } else if (data is uint) { dataDescriptor->Size = (uint)sizeof(uint); uint *uintptr = (uint *)dataBuffer; * uintptr = (uint)data; dataDescriptor->Ptr = (ulong)uintptr; } else if (data is UInt64) { dataDescriptor->Size = (uint)sizeof(ulong); UInt64 *ulongptr = (ulong *)dataBuffer; * ulongptr = (ulong)data; dataDescriptor->Ptr = (ulong)ulongptr; } else if (data is char) { dataDescriptor->Size = (uint)sizeof(char); char *charptr = (char *)dataBuffer; * charptr = (char)data; dataDescriptor->Ptr = (ulong)charptr; } else if (data is byte) { dataDescriptor->Size = (uint)sizeof(byte); byte *byteptr = (byte *)dataBuffer; * byteptr = (byte)data; dataDescriptor->Ptr = (ulong)byteptr; } else if (data is short) { dataDescriptor->Size = (uint)sizeof(short); short *shortptr = (short *)dataBuffer; * shortptr = (short)data; dataDescriptor->Ptr = (ulong)shortptr; } else if (data is sbyte) { dataDescriptor->Size = (uint)sizeof(sbyte); sbyte *sbyteptr = (sbyte *)dataBuffer; * sbyteptr = (sbyte)data; dataDescriptor->Ptr = (ulong)sbyteptr; } else if (data is ushort) { dataDescriptor->Size = (uint)sizeof(ushort); ushort *ushortptr = (ushort *)dataBuffer; * ushortptr = (ushort)data; dataDescriptor->Ptr = (ulong)ushortptr; } else if (data is float) { dataDescriptor->Size = (uint)sizeof(float); float *floatptr = (float *)dataBuffer; * floatptr = (float)data; dataDescriptor->Ptr = (ulong)floatptr; } else if (data is double) { dataDescriptor->Size = (uint)sizeof(double); double *doubleptr = (double *)dataBuffer; * doubleptr = (double)data; dataDescriptor->Ptr = (ulong)doubleptr; } else if (data is bool) { // WIN32 Bool is 4 bytes dataDescriptor->Size = 4; int *intptr = (int *)dataBuffer; if (((bool)data)) { *intptr = 1; } else { *intptr = 0; } dataDescriptor->Ptr = (ulong)intptr; } else if (data is Guid) { dataDescriptor->Size = (uint)sizeof(Guid); Guid *guidptr = (Guid *)dataBuffer; * guidptr = (Guid)data; dataDescriptor->Ptr = (ulong)guidptr; } else if (data is decimal) { dataDescriptor->Size = (uint)sizeof(decimal); decimal *decimalptr = (decimal *)dataBuffer; * decimalptr = (decimal)data; dataDescriptor->Ptr = (ulong)decimalptr; } else if (data is DateTime) { long dateTimeTicks = ((DateTime)data).ToFileTimeUtc(); dataDescriptor->Size = (uint)sizeof(long); long *longptr = (long *)dataBuffer; * longptr = dateTimeTicks; dataDescriptor->Ptr = (ulong)longptr; } else { if (data is System.Enum) { Type underlyingType = Enum.GetUnderlyingType(data.GetType()); if (underlyingType == typeof(int)) { data = ((IConvertible)data).ToInt32(null); goto Again; } else if (underlyingType == typeof(long)) { data = ((IConvertible)data).ToInt64(null); goto Again; } } //To our eyes, everything else is a just a string if (data == null) { sRet = ""; } else { sRet = data.ToString(); } dataDescriptor->Size = (uint)((sRet.Length + 1) * 2); return(sRet); } return(null); }