Передающие указатели от неуправляемого кода

Если вам просто нужно добавить нули к вашим данным, чтобы получить ту же глубину, вот способ сделать это:

7
задан JaredPar 7 May 2009 в 14:48
поделиться

3 ответа

Вам нужно будет использовать IntPtr и Marshal, который IntPtr, в любую структуру C #, в которую вы хотите ее вставить. В вашем случае вам придется маршалировать ее в int [].

Это делается в несколько этапов:

  • Выделить неуправляемый дескриптор
  • Вызвать функцию с помощью неуправляемого массива
  • Преобразовать массив в управляемый байтовый массив
  • Преобразовать байтовый массив в массив 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, иначе вы рискуете пропустить неуправляемый дескриптор.

8
ответ дан 7 December 2019 в 01:25
поделиться

Если я понимаю, что вы пытаетесь сделать, это должно сработать для вас.

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 # делает маршаллинг для вас в фоновом режиме.

Надеюсь, это даст вам представление о том, что происходит на немного более низком уровне в любом случае.

2
ответ дан 7 December 2019 в 01:25
поделиться

При написании объявления 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 в аргументах, передаваемых по ссылке.

0
ответ дан 7 December 2019 в 01:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: