C# 互操作返回 System.Access.Violation

C# interop returning System.Access.Violation

我正在尝试通过 C# Interop 使用 C 函数,但我收到一个函数的访问冲突。我尝试了很多方法,但似乎无法解决这个问题。

这里是需要改成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))

此时一切正确。设备数组中包含正确的信息。

我现在继续(我只是硬编码 select 第一个设备)

       chosenIdx = 0;

       var chosenDevice = devices[chosenIdx];

       err = SelectDevice(chosenDevice);

最后一个函数returns一个System.Access违规

我尝试了一大堆东西,但最终都得到了相同的结果。我怀疑它与 HANDLE 有关,但我不确定。 感谢您的帮助。

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);