MemoryLock 1.0.0-beta
See the version list below for details.
dotnet add package MemoryLock --version 1.0.0-beta
NuGet\Install-Package MemoryLock -Version 1.0.0-beta
<PackageReference Include="MemoryLock" Version="1.0.0-beta" />
<PackageVersion Include="MemoryLock" Version="1.0.0-beta" />
<PackageReference Include="MemoryLock" />
paket add MemoryLock --version 1.0.0-beta
#r "nuget: MemoryLock, 1.0.0-beta"
#:package MemoryLock@1.0.0-beta
#addin nuget:?package=MemoryLock&version=1.0.0-beta&prerelease
#tool nuget:?package=MemoryLock&version=1.0.0-beta&prerelease
Memory Lock
Allocate memories in C# by using "using" statement.
What is this ?
This is a wrapper library for :
System.Runtime.InteropServices.Marshal.AllocCoTaskMemSystem.Runtime.InteropServices.Marshal.FreeCoTaskMemSystem.Runtime.InteropServices.Marshal.AllocHGlobalSystem.Runtime.InteropServices.Marshal.Marshal.FreeHGlobalSystem.Runtime.InteropServices.GCHandle.AllocSystem.Runtime.InteropServices.GCHandle.Free
They are used for allocating memories which is never collected or moved by GC (Garbage Collector).
People use these functions when they want to call native codes by P/Invoke because passing some parameters to C++ requires to prepare memories not moved.
Why wrap them ?
After allocating memories, we have to release them.
It is so bothered. Isn't it ?
That is why I implemented this library.
Using Memory Lock, you don't have to pay attention to memories whether they are released or not.
Watch the following code :
// using System.Runtime.InteropServices;
// Allocate memories by "size"
var pointer = Marshal.AllocCoTaskMem(size);
//
// Do something
//
// Release memories
Marshal.FreeCoTaskMem(pointer);
// "pointer" refers to nothing but the parameter alives.
// If you use "pointer" here, it will cause "undefined behaviour".
This is an ordinary code using Marshal.AllocCoTaskMem.
I think it has some problems :
- When you forget to write Free(), It is too difficult to realize the mistake.
- You can access the pointer which is released easily.
With Memory Lock, you can write the following code :
// using CapraLib.MemoryLock;
// Allocate memories
using(var allocated = new CoTaskMemAllocater(out var pointer, size))
{
// Do something
}
// You can't access to the pointer here !
// And they are already released !
This library solves the problems clearly !
In C# 8, you can use this with "using declarations".
Examples
Allocate 100 bytes
using(var allocated = new CoTaskMemAllocater(out var pointer, 100))
// OR
using(var allocated = new HGlobalAllocater(out var pointer, 100))
{
// Do something with "pointer" !
}
The following table will help you.
| Allocate memory by ... | Size | Object(Non type) | Unmanaged object |
|---|---|---|---|
| CoTaskMemAllocater | ✔️ | ||
| HGlobalAllocater | ✔️ | ||
| GCAllocater | ✔️ | ||
| CoTaskMemAllocater<T> | ✔️ | ||
| HGlobalAllocater<T> | ✔️ | ||
| GCAllocater<T> | ✔️ |
Unmanaged object includes :
sbyte,byte,short,ushort,int,uint,long,ulong,char,float,double,decimal,bool- User defined structs which has attribute,
[StructLayout(LayoutKind.Sequential)]
Using struct
If you have a struct :
// StructLayout should be LayoutKind.Sequential
// when it is used in Memory Lock
[StructLayout(LayoutKind.Sequential)]
public struct Vector
{
public float x;
public float y;
public float z;
}
And a native function :
// Assign values to vec
[DllImport("Some.dll")]
static extern void ChangeAll(IntPtr vec, float x, float y, float z);
On that time, you can write the following code :
// using CaprLib.MemoryLock;
var vec = new Vector();
vec.x = 10f;
using(var allocated = new CoTaskMemAllocater<Vector>(out var pointer, vec))
{
// Assign another values to the pointer
ChangeAll(pointer, 15f, 19f, 23f);
// Copy from unmanaged memory to managed.
allocated.SetResult(out vec);
}
Console.WriteLine($"vec.x = {vec.x}"); // vec.x = 15
Before releasing the memory, you can call void SetResults(out T vec) to save changes to managed items.
This function is implemented in
CoTaskMemAllocater<T>HGlobalAllocater<T>GCAllocater<T>
Author
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.1 is compatible. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
-
.NETCoreApp 2.1
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0 | 760 | 9/9/2019 |
| 1.1.0 | 624 | 9/4/2019 |
| 1.0.0 | 629 | 8/31/2019 |
| 1.0.0-beta | 491 | 8/23/2019 |