I am developing an application that needs to interact with the Video4Linux abstraction. The application is developed in C # using a mono-structure.
The problem I am facing is that I cannot P / call a system call ioctl. Or rather, I can P / call it, but it drops a lot.
The extern declaration is as follows:
[DllImport("libc", EntryPoint = "ioctl", SetLastError = true)]
private extern static int KernelIoCtrl(int fd, int request, IntPtr data);
So far so good.
The actual procedure using is KernelIoCtrlas follows:
protected virtual int Control(IoSpecification request, object data)
{
GCHandle dataHandle;
IntPtr dataPointer = IntPtr.Zero;
try {
if (data != null) {
dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
dataPointer = dataHandle.AddrOfPinnedObject();
}
int result = KernelIoCtrl(mFileDescriptor, request.RequestCode, dataPointer);
int errno = Marshal.GetLastWin32Error();
if (errno != (int)ErrNumber.NoError)
throw new System.ComponentModel.Win32Exception(errno);
return (result);
} finally {
if (dataPointer != IntPtr.Zero)
dataHandle.Free();
}
}
All of the above codes seem to be good. The class is IoSpecificationused to compute the I / O request code following the header specification (basically this follows the macro _IOCdeclared in /usr/include/linux/asm/ioctl.h.
A parameter datais a structure declared as follows:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Capability
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string Driver;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string Device;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string BusInfo;
public UInt32 Version;
public CapabilityFlags Capabilities;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
public UInt32[] Reserved;
}
( /usr/include/linux/videodev2.h):
struct v4l2_capability {
__u8 driver[16];
__u8 card[32];
__u8 bus_info[32];
__u32 version;
__u32 capabilities;
__u32 reserved[4];
};
IOCTL, KernelIoCtrl ( errno EINVAL). ( IOCTRL), .
, , , , .
, - , ioctl ( ):
int ioctl(int d, int request, ...);
, int ioctl(int d, int request, void*);, , IOCTRL .