C# взаимодействие, возвращающее System.Access.Violation - PullRequest
0 голосов
/ 20 января 2020

Я пытаюсь использовать функцию C через C# Interop, и я получаю нарушение прав доступа для одной функции. Я пробовал несколько вещей, и я не могу решить эту проблему.

Вот код C, который необходимо изменить на c# код:

 typedef struct
 {
    char SerNo[64];

    unsigned char hwVer; 

    HANDLE device; // Set by the API on return from SelectDevice()

 } DeviceT;

Эта структура используется следующей функцией:

    error = GetDevices(DeviceT *devices, unsigned int *numDevs, unsigned int maxDevs)

В коде C есть еще одна функция:

    error = SelectDevice(DeviceT *device)

Итак, я начал с определения DeviceT. Я попробовал несколько способов, но остановился на этом, поскольку он прост:

    [StructLayout(LayoutKind.Sequential)]

    public struct DeviceT
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public char[] SerNo;

        public byte hwVer;

        public IntPtr device;
    }

Для функции GetDevices было задано следующее:

    [DllImport("file.dll", CallingConvention = CallingConvention.Cdecl)]
    public unsafe static extern  ErrT GetDevices([In, Out] DeviceT[] devices, uint* numDevs, uint maxDev);

Для функции SelectDevices было задано следующее:

     [DllImport("file.dll", CallingConvention = CallingConvention.Cdecl)]
    public unsafe static extern ErrT SelectDevice([In, Out] DeviceT devices);

Код выглядит так:

       uint numDevs = 6;
       uint maxDev = 6;
       uint chosenIdx = 0;

       DeviceT[] devices = new DeviceT[6];

       err = GetDevices(devices, &NumberOfDevices, maxDev))

На данный момент все правильно. Массив устройств содержит правильную информацию.

Теперь я продолжаю (я просто жестко определяю код первого устройства)

       chosenIdx = 0;

       var chosenDevice = devices[chosenIdx];

       err = SelectDevice(chosenDevice);

Эта последняя функция возвращает нарушение System.Access

Я перепробовал кучу всего, но в итоге все получилось с одинаковым результатом. Я подозреваю, что это как-то связано с РУЧКОЙ, но я не уверен. Спасибо за любую помощь.

1 Ответ

1 голос
/ 20 января 2020

SelectDevice занимает DeviceT *, а ваша подпись P / Invoke - DeviceT. То есть вы передаете DeviceT по значению, а не передаете указатель.

Попробуйте:

[DllImport("file.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ErrT SelectDevice([In, Out] ref DeviceT devices);

err = SelectDevice(ref chosenDevice);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...