簡體   English   中英

在 c# 中分配“非托管”memory

[英]allocating "unmanaged" memory in c#

我正在 c# 中編寫一個使用 C++ 庫的程序,出於某種原因,我需要分配一個非托管緩沖區以將其傳遞給庫。 c#有沒有辦法做到這一點? 基本上我只需要在 C# 中做一個 malloc ...

謝謝

嘗試這樣的事情:

using System;
using System.Runtime.InteropServices;

class Example
{
    static void Main()
    {
        IntPtr pointer = Marshal.AllocHGlobal(1024);
    }
}

這使用Marshal.AllocHGlobal方法:

使用指定的字節數從進程的非托管內存中分配內存。

您也可以使用字節數組。

您通過使用不安全的例程和固定語句來執行此操作:

static unsafe void PerformOperation()
{
    byte[] buf = new byte[1024];
    fixed (void* ptr = &buf[0])
    {
        SomeUnmanagedFunction(new IntPtr(ptr));
    }
}

問題 - 這是一個重要問題 - 是SomeUnmanagedFunction在返回並且代碼退出固定塊后不允許觸摸該指針。 所以如果你做這樣的事情:

static void PerformFabulousTrick()
{
    byte[] buf = new byte[1024];
    fixed (void *ptr = &buf[0])
    {
        SetBuffer(ptr, buf.Length);
    }
    FillBuffer(); // puts data in buf - NOT - may crash hard
}

除了麻煩,你什么都不要求。 在這種情況下,您可能希望使用GCHandle ,它可以固定堆中的托管對象。 這也很麻煩,因為你需要及時取消它,或者你可能會破壞你的堆。

一般來說,我建議你確保你正確地調用P /函數,這樣也許編組人員可以為你做這項工作。 我喜歡修復比GlobalAlloc更好,因為它的范圍很明確。 我無法決定哪個最不喜歡GlobalAlloc和GCHandle。 兩者都要求你做更多的工作,因為GC或語言不會為你做。

這就是我們需要通過使用特定字節數來分配和釋放非托管內存的方式。

// Demonstrate how to call GlobalAlloc and 
// GlobalFree using the Marshal class.
IntPtr hglobal = Marshal.AllocHGlobal(100);
Marshal.FreeHGlobal(hglobal)

多年后,與此同時:在 .net6、7 中,MS 為我們提供了 class“ NativeMemory ”以及“ AlignedAlloc ”等方法,這可能對矢量化應用程序很有用: MS 為這個例子寫道

public static void* AlignedAlloc (UIntPtr byteCount, UIntPtr alignment);

“此方法是 C aligned_alloc API 或依賴於平台的對齊分配 API(例如 Win32 上的 _aligned_malloc)的薄包裝。”

當然,在那種情況下沒有垃圾收集。 必須自己釋放 memory 以避免 memory 泄漏,方法是使用“ AlignedFree ”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM