簡體   English   中英

從非托管代碼傳遞指針

[英]Passing pointers from unmanaged code

我有一個導入C dll的C#項目,dll有這個功能:

int primary_read_serial(int handle, int *return_code, int *serial, int length);

我想訪問serial參數。 我實際上已經讓它返回串行參數的一個字符,但我不確定我在做什么,並且想要了解發生了什么,當然讓它工作。

所以,我非常確定正在訪問dll,沒有指針的其他函數工作正常。 我該如何處理指針? 我必須編組嗎? 也許我必須有一個固定的地方來放置數據嗎?

解釋會很棒。

謝謝! 理查德

你必須使用IntPtr和Marshal將IntPtr放入你想要放入的任何C#結構中。在你的情況下,你必須將它編組為int []。

這是通過幾個步驟完成的:

  • 分配一個非托管句柄
  • 使用unamanged數組調用該函數
  • 將數組轉換為托管字節數組
  • 將字節數組轉換為int數組
  • 釋放非托管句柄

該代碼應該給你一個想法:

// The import declaration
[DllImport("Library.dll")]
public static extern int primary_read_serial(int, ref int, IntPtr, int) ;


// Allocate unmanaged buffer
IntPtr serial_ptr = Marshal.AllocHGlobal(length * sizeof(int));

try
{
    // Call unmanaged function
    int return_code;
    int result = primary_read_serial(handle, ref return_code, serial_ptr, length);

    // Safely marshal unmanaged buffer to byte[]
    byte[] bytes = new byte[length * sizeof(int)];
    Marshal.Copy(serial_ptr, bytes, 0, length);

    // Converter to int[]
    int[] ints = new int[length];
    for (int i = 0; i < length; i++)
    {
        ints[i] = BitConverter.ToInt32(bytes, i * sizeof(int));
    }

}
finally
{
    Marshal.FreeHGlobal(serial_ptr);
}

不要忘記try-finally,否則你將冒險泄露非托管句柄。

如果我明白你要做什么,這應該適合你。

unsafe
{
    int length = 1024; // Length of data to read.

    fixed (byte* data = new byte[length]) // Pins array to stack so a pointer can be retrieved.
    {
        int returnCode;
        int retValue = primary_read_serial(0, &returnCode, data, length);

        // At this point, `data` should contain all the read data.
    }
}

JaredPar為您提供了簡單的方法,它只是為了更改您的外部函數聲明,以便C#在后台為您進行編組。

希望這可以讓你了解在較低水平發生的事情。

在編寫該函數的P / invoke聲明時,請嘗試使用關鍵字ref作為指針參數,如下所示:

[DllImport("YouDll.dll", EntryPoint = "primary_read_serial")]
public static extern int primary_read_serial(int, ref int, ref int, int) ;

我不確定你是否需要在C#中指定參數名稱。 請記住,在調用該方法時,您還必須在通過引用傳遞的參數中使用ref。

暫無
暫無

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

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