C# 调度程序的P/Invoke签名
我需要为Linux函数提供p/Invoke签名,从Mono上运行的C#代码调用C# 调度程序的P/Invoke签名,c#,linux,mono,pinvoke,C#,Linux,Mono,Pinvoke,我需要为Linux函数提供p/Invoke签名,从Mono上运行的C#代码调用 int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); “开放硬件监视器”项目中的类将其定义为: [DllImport(LIBC)] public static extern int sched_setaffinity(int pid, IntPtr maskSize,
int sched_setaffinity(pid_t pid, size_t cpusetsize,
cpu_set_t *mask);
“开放硬件监视器”项目中的类将其定义为:
[DllImport(LIBC)]
public static extern int sched_setaffinity(int pid, IntPtr maskSize,
ref ulong mask);
但是,项目使用不同的签名:
[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
SetLastError=true, EntryPoint="sched_setaffinity")]
protected static extern int sched_setaffinity (long pid, int num_bytes,
byte[] affinity);
是两个签名都正确,还是其中一个签名有误?它们是否可跨32位和64位体系结构移植
我假设第一个参数应该是int
,而不是long
,因为pid\u t
在32位和64位平台上都是有符号的32位整数(per)。同样,第二个应该是UIntPtr
或IntPtr
per。但是,我不知道如何处理第三个参数
编辑:基于Simon Mourier的评论:我从cpu\u set\u t*
类型中得出结论,第三个参数应该是指针。ref-ulong
符合条件吗?我很想使用这种类型,因为它使宏更容易实现;例如,单个处理器id
的掩码可以计算为:
ulong mask = 1UL << id;
ulong mask=1UL根据我的经验,我选择了前一个选项(在Linux上运行良好)
正如您所发现的,cpu_set_t只是一个无符号长整数数组。因此,我将像下面这样声明函数:
[DllImport("libc.so.6", SetLastError=true)]
private static extern int sched_setaffinity(
int pid,
IntPtr cpusetsize,
ulong[] cpuset
);
我同意intpid
和IntPtr maskSize
。对于cpu集合,我假设它默认为Cint
,因为它在sched.h中没有明确定义。重要的是它必须是一个指针,这个指针必须由内部CPU_*宏(CPU_0等)操作。因此,您可以使用byte[]或int[],但也需要将CPU_*宏公开给.NET世界。问题是CPU_set\u t
可能大于ulong
@DavidHeffernan:这需要一台大于64核的机器,不是吗?@DavidHeffernan:,但是大多数程序员不太可能在未来几年内遇到它们。即使是.NET框架也会在这样的机器上崩溃。谢谢David!我假设cpusetsize
应该是整个数组的大小(例如4*sizeof(ulong)
如果它包含四个元素)(我需要几周的时间来测试答案;我目前没有访问Linux机器的权限。)
[DllImport("libc.so.6", SetLastError=true)]
private static extern int sched_setaffinity(
int pid,
IntPtr cpusetsize,
ulong[] cpuset
);