我正在尝试通过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有关,但我不确定。感谢您的帮助。
[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);