private unsafe FileVersionInfo(string fileName) { _fileName = fileName; uint infoSize = Interop.Version.GetFileVersionInfoSizeEx(Interop.Version.FileVersionInfoType.FILE_VER_GET_LOCALISED, _fileName, out _); if (infoSize != 0) { void *memPtr = NativeMemory.Alloc(infoSize); try { if (Interop.Version.GetFileVersionInfoEx( Interop.Version.FileVersionInfoType.FILE_VER_GET_LOCALISED | Interop.Version.FileVersionInfoType.FILE_VER_GET_NEUTRAL, _fileName, 0U, infoSize, memPtr)) { // Some dlls might not contain correct codepage information, in which case the lookup will fail. Explorer will take // a few shots in dark. We'll simulate similar behavior by falling back to the following lang-codepages. uint lcp = GetLanguageAndCodePage(memPtr); _ = GetVersionInfoForCodePage(memPtr, lcp.ToString("X8")) || (lcp != 0x040904B0 && GetVersionInfoForCodePage(memPtr, "040904B0")) || // US English + CP_UNICODE (lcp != 0x040904E4 && GetVersionInfoForCodePage(memPtr, "040904E4")) || // US English + CP_USASCII (lcp != 0x04090000 && GetVersionInfoForCodePage(memPtr, "04090000")); // US English + unknown codepage } } finally { NativeMemory.Free(memPtr); } } }
/// <summary> /// Initialize the marshaller with a managed string and requested buffer. /// </summary> /// <param name="managed">The managed string</param> /// <param name="buffer">A request buffer of at least size, <see cref="BufferSize"/>.</param> public void FromManaged(string?managed, Span <byte> buffer) { _allocated = false; if (managed is null) { _unmanagedValue = null; return; } // >= for null terminator // Use the cast to long to avoid the checked operation if ((long)Marshal.SystemMaxDBCSCharSize * managed.Length >= buffer.Length) { // Calculate accurate byte count when the provided stack-allocated buffer is not sufficient int exactByteCount = Marshal.GetAnsiStringByteCount(managed); // Includes null terminator if (exactByteCount > buffer.Length) { buffer = new Span <byte>((byte *)NativeMemory.Alloc((nuint)exactByteCount), exactByteCount); _allocated = true; } } _unmanagedValue = (byte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(buffer)); Marshal.GetAnsiStringBytes(managed, buffer); // Includes null terminator }
/// <summary> /// The factory method for <see cref="ID2D1Factory1.RegisterEffectFromString"/>. /// </summary> /// <param name="shaderId">The <see cref="Guid"/> for the shader.</param> /// <param name="numberOfInputs">The number of inputs for the shader.</param> /// <param name="bytecode">The shader bytecode.</param> /// <param name="bytecodeSize">The size of <paramref name="bytecode"/>.</param> /// <param name="d2D1TransformMapper">The <see cref="D2D1TransformMapper"/> instance to use for the effect.</param> /// <param name="effectImpl">The resulting effect instance.</param> /// <returns>This always returns <c>0</c>.</returns> private static int Factory( Guid shaderId, int numberOfInputs, byte *bytecode, int bytecodeSize, D2D1TransformMapper?d2D1TransformMapper, IUnknown **effectImpl) { PixelShaderEffect * @this = (PixelShaderEffect *)NativeMemory.Alloc((nuint)sizeof(PixelShaderEffect)); *@this = default; @this->lpVtblForID2D1EffectImpl = VtblForID2D1EffectImpl; @this->lpVtblForID2D1DrawTransform = VtblForID2D1DrawTransform; @this->referenceCount = 1; @this->shaderId = shaderId; @this->numberOfInputs = numberOfInputs; @this->bytecode = bytecode; @this->bytecodeSize = bytecodeSize; @this->d2D1TransformMapperHandle = GCHandle.Alloc(d2D1TransformMapper); *effectImpl = (IUnknown *)@this; return(S.S_OK); }
public PixelZone(int row, int column, int xMin, int xMax, int yMin, int yMax, int stride, int bitDepth, PixelZonesTotals totals, int totalsIndex) { Row = row; Column = column; TopLeft = new Point(xMin, yMin); BottomRight = new Point(xMax, yMax); Width = BottomRight.X - TopLeft.X; Height = BottomRight.Y - TopLeft.Y; TotalR = totals.TotalR + totalsIndex; TotalG = totals.TotalG + totalsIndex; TotalB = totals.TotalB + totalsIndex; Count = totals.Count + totalsIndex; AvgR = totals.AvgR + totalsIndex; AvgG = totals.AvgG + totalsIndex; AvgB = totals.AvgB + totalsIndex; //The zones cover a rectangular area of the image, but the images are stored in a sequential array, so we need to have a range // for each y coordinate that the rectangle covers. nuint bytesLength = (nuint)(sizeof(ZonePixelRange) * Height); PixelRanges = (ZonePixelRange *)NativeMemory.Alloc(bytesLength); for (int y = TopLeft.Y, i = 0; y < BottomRight.Y; ++y, ++i) { var start = GetImageCoordinate(stride, TopLeft.X, y, bitDepth); var length = GetImageCoordinate(stride, BottomRight.X, y, bitDepth) - start; PixelRanges[i] = new ZonePixelRange(start, length); } }
public void AllocZeroByteCountTest() { void *ptr = NativeMemory.Alloc(0); Assert.True(ptr != null); NativeMemory.Free(ptr); }
/// <summary> /// Initializes the marshaller with a managed string and requested buffer. /// </summary> /// <param name="managed">The managed string with which to initialize the marshaller.</param> /// <param name="buffer">The request buffer whose size is at least <see cref="BufferSize"/>.</param> public void FromManaged(string?managed, Span <byte> buffer) { _allocated = false; if (managed is null) { _unmanagedValue = null; return; } const int MaxUtf8BytesPerChar = 3; // >= for null terminator // Use the cast to long to avoid the checked operation if ((long)MaxUtf8BytesPerChar * managed.Length >= buffer.Length) { // Calculate accurate byte count when the provided stack-allocated buffer is not sufficient int exactByteCount = checked (Encoding.UTF8.GetByteCount(managed) + 1); // + 1 for null terminator if (exactByteCount > buffer.Length) { buffer = new Span <byte>((byte *)NativeMemory.Alloc((nuint)exactByteCount), exactByteCount); _allocated = true; } } _unmanagedValue = (byte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(buffer)); int byteCount = Encoding.UTF8.GetBytes(managed, buffer); buffer[byteCount] = 0; // null-terminate }
public void AllocZeroElementCountTest() { void *ptr = NativeMemory.Alloc(0, 1); Assert.True(ptr != null); NativeMemory.Free(ptr); }
private static unsafe void AllocNullTerminatedArray(string[] arr, ref byte **arrPtr) { nuint arrLength = (nuint)arr.Length + 1; // +1 is for null termination // Allocate the unmanaged array to hold each string pointer. // It needs to have an extra element to null terminate the array. // Zero the memory so that if any of the individual string allocations fails, // we can loop through the array to free any that succeeded. // The last element will remain null. arrPtr = (byte **)NativeMemory.AllocZeroed(arrLength, (nuint)sizeof(byte *)); // Now copy each string to unmanaged memory referenced from the array. // We need the data to be an unmanaged, null-terminated array of UTF8-encoded bytes. for (int i = 0; i < arr.Length; i++) { string str = arr[i]; int byteLength = Encoding.UTF8.GetByteCount(str); arrPtr[i] = (byte *)NativeMemory.Alloc((nuint)byteLength + 1); //+1 for null termination int bytesWritten = Encoding.UTF8.GetBytes(str, new Span <byte>(arrPtr[i], byteLength)); Debug.Assert(bytesWritten == byteLength); arrPtr[i][bytesWritten] = (byte)'\0'; // null terminate } }
public void AllocZeroElementSizeTest() { void *ptr = NativeMemory.Alloc(1, 0); Assert.True(ptr != null); NativeMemory.Free(ptr); }
public void NativeLibTest() { const nuint i = 256; var a = NativeMemory.Alloc(i); Assert.AreEqual(Mem._msize(a), i); }
/// <summary> /// Creates and initializes a new <see cref="ID3DIncludeForD2DHelpers"/> instance. /// </summary> /// <returns>A pointer to a new <see cref="ID3DIncludeForD2DHelpers"/> instance.</returns> public static ID3DIncludeForD2DHelpers *Create() { ID3DIncludeForD2DHelpers * @this = (ID3DIncludeForD2DHelpers *)NativeMemory.Alloc((nuint)sizeof(ID3DIncludeForD2DHelpers)); @this->lpVtbl = Vtbl; return(@this); }
// From the same source: // "Each buffer must be at least the size of a system memory page and must be aligned on a system // memory page size boundary. The system reads/writes one system memory page of data into/from each buffer." // This method returns true if the buffers can be used by // the Windows scatter/gather API, which happens when they are: // 1. aligned at page size boundaries // 2. exactly one page long each (our own requirement to prevent partial reads) // 3. not bigger than 2^32 - 1 in total // This function is also responsible for pinning the buffers if they // are suitable and they must be unpinned after the I/O operation completes. // It also returns a pointer with the segments to be passed to the // Windows API, and the total size of the buffers that is needed as well. // The pinned MemoryHandles and the pointer to the segments must be cleaned-up // with the CleanupScatterGatherBuffers method. private static unsafe bool TryPrepareScatterGatherBuffers <T, THandler>(IReadOnlyList <T> buffers, THandler handler, out MemoryHandle[] handlesToDispose, out IntPtr segmentsPtr, out int totalBytes) where THandler : struct, IMemoryHandler <T> { int pageSize = s_cachedPageSize; Debug.Assert(BitOperations.IsPow2(pageSize), "Page size is not a power of two."); // We take advantage of the fact that the page size is // a power of two to avoid an expensive modulo operation. long alignedAtPageSizeMask = pageSize - 1; int buffersCount = buffers.Count; handlesToDispose = new MemoryHandle[buffersCount]; segmentsPtr = IntPtr.Zero; totalBytes = 0; // "The array must contain enough elements to store nNumberOfBytesToWrite bytes of data, and one element for the terminating NULL. " long *segments = (long *)NativeMemory.Alloc((nuint)(buffersCount + 1), sizeof(long)); segments[buffersCount] = 0; bool success = false; try { long totalBytes64 = 0; for (int i = 0; i < buffersCount; i++) { T buffer = buffers[i]; int length = handler.GetLength(in buffer); totalBytes64 += length; if (length != pageSize || totalBytes64 > int.MaxValue) { return(false); } MemoryHandle handle = handlesToDispose[i] = handler.Pin(in buffer); long ptr = segments[i] = (long)handle.Pointer; if ((ptr & alignedAtPageSizeMask) != 0) { return(false); } } segmentsPtr = (IntPtr)segments; totalBytes = (int)totalBytes64; success = true; return(true); } finally { if (!success) { CleanupScatterGatherBuffers(handlesToDispose, (IntPtr)segments); } } }
public void TestNativeAlloc() { for (var i = 0; i < IterCount; i++) { var p = (byte *)NativeMemory.Alloc((nuint)Size); Consume(&p); NativeMemory.Free(p); } }
private void Resize() { int newCapacity = data->capacity * 2; byte *newArr = NativeMemory.Alloc(data->structSize * newCapacity, NativeMemory.NativeMemoryType.RawList); NativeMemory.Copy(newArr, data->arrayPtr, data->structSize * data->capacity); NativeMemory.Free(data->arrayPtr); data->arrayPtr = newArr; data->capacity = newCapacity; }
/** * Allocates 128 byte aligned memory block for binary serialized data * Stores pointer to memory in gMemBlocks for later deallocation */ static void *createAlignedBlock(uint size) { Debug.Assert(gMemBlockCount < MAX_MEMBLOCKS); byte *baseAddr = (byte *)NativeMemory.Alloc(size + PX_SERIAL_FILE_ALIGN - 1); gMemBlocks[gMemBlockCount++] = baseAddr; void *alignedBlock = (void *)(((nint)(baseAddr) + PX_SERIAL_FILE_ALIGN - 1) & ~(PX_SERIAL_FILE_ALIGN - 1)); return(alignedBlock); }
private void Reserve(int count) { if (_handles.Length < count) { _handles = new MemoryHandle[count]; FreeNativeMemory(); _buffers = (QUIC_BUFFER *)NativeMemory.Alloc((nuint)count, (nuint)sizeof(QUIC_BUFFER)); } _count = count; }
public void ReallocZeroSizeTest() { void *ptr = NativeMemory.Alloc(1); Assert.True(ptr != null); void *newPtr = NativeMemory.Realloc(ptr, 0); Assert.True(newPtr != null); NativeMemory.Free(newPtr); }
public static unsafe IntPtr GetGenericMethodFunctionPointer(IntPtr canonFunctionPointer, IntPtr instantiationArgument) { if (instantiationArgument == IntPtr.Zero) { return(canonFunctionPointer); } lock (s_genericFunctionPointerDictionary) { var key = new GenericMethodDescriptorInfo { MethodFunctionPointer = canonFunctionPointer, InstantiationArgument = instantiationArgument }; uint index = 0; if (!s_genericFunctionPointerDictionary.TryGetValue(key, out index)) { // Capture new index value index = s_genericFunctionPointerNextIndex; int newChunkIndex = (int)(index / c_genericDictionaryChunkSize); uint newSubChunkIndex = index % c_genericDictionaryChunkSize; // Generate new chunk if existing chunks are insufficient if (s_genericFunctionPointerCollection.Count <= newChunkIndex) { System.Diagnostics.Debug.Assert(newSubChunkIndex == 0); // New generic descriptors are allocated on the native heap and not tracked in the GC. IntPtr pNewMem = (IntPtr)NativeMemory.Alloc(c_genericDictionaryChunkSize, (nuint)sizeof(GenericMethodDescriptor)); s_genericFunctionPointerCollection.Add(pNewMem); } ((GenericMethodDescriptor *)s_genericFunctionPointerCollection[newChunkIndex])[newSubChunkIndex] = new GenericMethodDescriptor(canonFunctionPointer, instantiationArgument); s_genericFunctionPointerDictionary.LookupOrAdd(key, index); // Now that we can no longer have failed, update the next index. s_genericFunctionPointerNextIndex++; } // Lookup within list int chunkIndex = (int)(index / c_genericDictionaryChunkSize); uint subChunkIndex = index % c_genericDictionaryChunkSize; GenericMethodDescriptor *genericFunctionPointer = &((GenericMethodDescriptor *)s_genericFunctionPointerCollection[chunkIndex])[subChunkIndex]; System.Diagnostics.Debug.Assert(canonFunctionPointer == genericFunctionPointer->MethodFunctionPointer); System.Diagnostics.Debug.Assert(instantiationArgument == genericFunctionPointer->InstantiationArgument); return((IntPtr)((byte *)genericFunctionPointer + FatFunctionPointerOffset)); } }
public IOCompletionPoller(nint port) { Debug.Assert(port != 0); _port = port; if (!UnsafeInlineIOCompletionCallbacks) { _nativeEvents = (Interop.Kernel32.OVERLAPPED_ENTRY *) NativeMemory.Alloc(NativeEventCapacity, (nuint)sizeof(Interop.Kernel32.OVERLAPPED_ENTRY)); _events = new(default);
/// <summary> /// Creates and initializes a new <see cref="IDXGIFactory4As6Backcompat"/> instance. /// </summary> /// <param name="dxgiFactory4">The <see cref="IDXGIFactory4"/> instance to wrap.</param> /// <param name="dxgiFactory6">The resulting <see cref="IDXGIFactory6"/> instance.</param> public static void Create(IDXGIFactory4 *dxgiFactory4, IDXGIFactory6 **dxgiFactory6) { IDXGIFactory4As6Backcompat * @this = (IDXGIFactory4As6Backcompat *)NativeMemory.Alloc((nuint)sizeof(IDXGIFactory4As6Backcompat)); @this->lpVtbl = Vtbl; @this->dxgiFactory4 = dxgiFactory4; _ = dxgiFactory4->AddRef(); *dxgiFactory6 = (IDXGIFactory6 *)@this; }
public MessageBufferHG(MessageBufferHG right) { _wpos = right._wpos; _rpos = right._rpos; _size = right._size; _capacity = BitOperations.RoundUpToPowerOf2((uint)_size); _storage = NativeMemory.Alloc(_capacity); Buffer.MemoryCopy(right._storage, _storage, (ulong)_size, (ulong)_size); }
public MessageBufferHG(int initialSize) { if (initialSize <= 0) { throw new ArgumentOutOfRangeException(nameof(initialSize)); } _size = initialSize; _capacity = BitOperations.RoundUpToPowerOf2((uint)_size); _storage = NativeMemory.Alloc(_capacity); }
public NativeList(int capacity = 10) { if (capacity < 1) { capacity = 1; } data = (NativeListData *)NativeMemory.Alloc(NativeListData.SIZE, NativeMemory.NativeMemoryType.RawList); data->structSize = Marshal.SizeOf <NativeListData>(); data->capacity = capacity; data->length = 0; data->arrayPtr = NativeMemory.Alloc(data->structSize * data->capacity, NativeMemory.NativeMemoryType.RawList); }
/// <summary> /// 在指定地址创建对象 /// </summary> /// <param name="ptr"></param> /// <returns></returns> public static T Create(void *ptr = null) { if (ptr == null) ptr = NativeMemory.Alloc(size); fixed(void *headerPtr = header) Buffer.MemoryCopy(headerPtr, ptr, header.Length, header.Length); T ret = cast2T(new IntPtr(ptr)); ret.SetPtr(ptr); return(ret); }
public PixelZonesTotals(int length) { _length = length; nuint bytesLength = (nuint)(sizeof(int) * length); TotalR = (int *)NativeMemory.Alloc(bytesLength); TotalG = (int *)NativeMemory.Alloc(bytesLength); TotalB = (int *)NativeMemory.Alloc(bytesLength); Count = (int *)NativeMemory.Alloc(bytesLength); AvgR = (int *)NativeMemory.Alloc(bytesLength); AvgG = (int *)NativeMemory.Alloc(bytesLength); AvgB = (int *)NativeMemory.Alloc(bytesLength); }
public static SKBitmap?Decode(this UTexture2D texture, FTexture2DMipMap?mip, ETexturePlatform platform = ETexturePlatform.DesktopMobile) { if (!texture.IsVirtual && mip != null) { byte[] data; SKColorType colorType; switch (platform) { case ETexturePlatform.Playstation: PlaystationDecoder.DecodeTexturePlaystation(mip, texture.Format, texture.isNormalMap, out data, out colorType); break; case ETexturePlatform.NintendoSwitch: NintendoSwitchDecoder.DecodeTextureNSW(mip, texture.Format, texture.isNormalMap, out data, out colorType); break; default: DecodeTexture(mip, texture.Format, texture.isNormalMap, out data, out colorType); break; } var width = mip.SizeX; var height = mip.SizeY; var info = new SKImageInfo(width, height, colorType, SKAlphaType.Unpremul); var bitmap = new SKBitmap(); unsafe { var pixelsPtr = NativeMemory.Alloc((nuint)data.Length); fixed(byte *p = data) { Unsafe.CopyBlockUnaligned(pixelsPtr, p, (uint)data.Length); } bitmap.InstallPixels(info, new IntPtr(pixelsPtr), info.RowBytes, (address, _) => NativeMemory.Free(address.ToPointer())); } if (!texture.bRenderNearestNeighbor) { return(bitmap); } var resized = bitmap.Resize(new SKImageInfo(width, height), SKFilterQuality.None); bitmap.Dispose(); return(resized); } return(null); }
public unsafe IntPtr ToIntPtr() { lock (s_internedResolverHash) { IntPtr returnValue; if (s_internedResolverHash.TryGetValue(this, out returnValue)) { return(returnValue); } returnValue = (IntPtr)NativeMemory.Alloc((nuint)sizeof(OpenMethodResolver)); *((OpenMethodResolver *)returnValue) = this; s_internedResolverHash.Add(this, returnValue); return(returnValue); } }
/// <summary> /// The factory method for <see cref="ID2D1Factory1.RegisterEffectFromString"/>. /// </summary> /// <param name="shaderId">The <see cref="Guid"/> for the shader.</param> /// <param name="inputCount">The number of inputs for the shader.</param> /// <param name="inputTypes">The buffer with the types of inputs for the shader.</param> /// <param name="inputDescriptionCount">The number of available input descriptions.</param> /// <param name="inputDescriptions">The buffer with the available input descriptions for the shader.</param> /// <param name="pixelOptions">The pixel options for the shader.</param> /// <param name="bytecode">The shader bytecode.</param> /// <param name="bytecodeSize">The size of <paramref name="bytecode"/>.</param> /// <param name="bufferPrecision">The buffer precision for the resulting output buffer.</param> /// <param name="channelDepth">The channel depth for the resulting output buffer.</param> /// <param name="d2D1TransformMapper">The <see cref="D2D1TransformMapper"/> instance to use for the effect.</param> /// <param name="effectImpl">The resulting effect instance.</param> /// <returns>This always returns <c>0</c>.</returns> private static int Factory( Guid shaderId, int inputCount, D2D1PixelShaderInputType *inputTypes, int inputDescriptionCount, D2D1InputDescription *inputDescriptions, D2D1PixelOptions pixelOptions, byte *bytecode, int bytecodeSize, D2D1BufferPrecision bufferPrecision, D2D1ChannelDepth channelDepth, D2D1TransformMapper?d2D1TransformMapper, IUnknown **effectImpl) { PixelShaderEffect * @this; try { @this = (PixelShaderEffect *)NativeMemory.Alloc((nuint)sizeof(PixelShaderEffect)); } catch (OutOfMemoryException) { *effectImpl = null; return(E.E_OUTOFMEMORY); } *@this = default; @this->lpVtblForID2D1EffectImpl = VtblForID2D1EffectImpl; @this->lpVtblForID2D1DrawTransform = VtblForID2D1DrawTransform; @this->referenceCount = 1; @this->shaderId = shaderId; @this->inputCount = inputCount; @this->inputTypes = inputTypes; @this->inputDescriptionCount = inputDescriptionCount; @this->inputDescriptions = inputDescriptions; @this->pixelOptions = pixelOptions; @this->bytecode = bytecode; @this->bytecodeSize = bytecodeSize; @this->bufferPrecision = bufferPrecision; @this->channelDepth = channelDepth; @this->d2D1TransformMapperHandle = GCHandle.Alloc(d2D1TransformMapper); *effectImpl = (IUnknown *)@this; return(S.S_OK); }
public static int SetConstantBuffer(IUnknown *effect, byte *data, uint dataSize) { PixelShaderEffect * @this = (PixelShaderEffect *)effect; if (@this->constantBuffer is not null) { NativeMemory.Free(@this->constantBuffer); } void *buffer = NativeMemory.Alloc(dataSize); Buffer.MemoryCopy(data, buffer, dataSize, dataSize); @this->constantBuffer = (byte *)buffer; @this->constantBufferSize = (int)dataSize; return(S.S_OK); }
public static bool HashData(string str, Span <byte> destination, out int byteCount) { var count = Encoding.UTF8.GetByteCount(str); void *buff = NativeMemory.Alloc((uint)count); Span <byte> dataSpan = new Span <byte>(buff, count); Encoding.UTF8.GetBytes(str, dataSpan); try { return(HashData(dataSpan, destination, out byteCount)); } finally { NativeMemory.Free(buff); } }