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

问题描述 投票:0回答:1

我正在尝试通过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))

至此,一切正确。 devices阵列中包含正确的信息。

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

       chosenIdx = 0;

       var chosenDevice = devices[chosenIdx];

       err = SelectDevice(chosenDevice);

此最后一个函数返回违反System.Access的行为

我尝试了很多事情,但最终都得到了相同的结果。我怀疑这与HANDLE有关,但我不确定。感谢您的帮助。

c# interop
1个回答
1
投票

[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);
© www.soinside.com 2019 - 2024. All rights reserved.