【发布时间】:2014-05-06 10:48:35
【问题描述】:
我需要调用 Linux 函数sysinfo
它的声明是 int sysinfo(结构 sysinfo *info); 与
在 Linux 2.3.16 之前,sysinfo() 用于返回以下结构的信息:
struct sysinfo {
long uptime; /* Seconds since boot */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* Total usable main memory size */
unsigned long freeram; /* Available memory size */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* swap space still available */
unsigned short procs; /* Number of current processes */
char _f[22]; /* Pads structure to 64 bytes */
};
大小以字节为单位。
从 Linux 2.3.23 (i386)、2.3.48(所有架构)开始,结构为:
struct sysinfo {
long uptime; /* Seconds since boot */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* Total usable main memory size */
unsigned long freeram; /* Available memory size */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* swap space still available */
unsigned short procs; /* Number of current processes */
unsigned long totalhigh; /* Total high memory size */
unsigned long freehigh; /* Available high memory size */
unsigned int mem_unit; /* Memory unit size in bytes */
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding to 64 bytes */
};
这是我目前所拥有的:
函数pinvoke:
private const string DoesntFindLibC =@"/lib/x86_64-linux-gnu/libc.so.6";
[System.Runtime.InteropServices.DllImport(DoesntFindLibC)]
private static extern int sysinfo(ref sysinfo_t info);
还有结构映射:
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
struct sysinfo_t
{
public System.UIntPtr uptime; /* Seconds since boot */
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=3)]
public System.UIntPtr [] loads; /* 1, 5, and 15 minute load averages */
public System.UIntPtr totalram; /* Total usable main memory size */
public System.UIntPtr freeram; /* Available memory size */
public System.UIntPtr sharedram; /* Amount of shared memory */
public System.UIntPtr bufferram; /* Memory used by buffers */
// [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.
public System.UIntPtr totalswap; /* Total swap space size */
public System.UIntPtr freeswap; /* swap space still available */
public ushort procs; /* Number of current processes */
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=22)]
public char[] _f; /* Pads structure to 64 bytes */
}
问题是 C 代码中的“long”是特定于处理器架构的,因为在 x86 32 位 Linux 中,long 的大小是 32 位,而在 x86 64 位 Linux 中,它是 64 位,所以我必须取 IntPtr,因为它是无符号的,所以我取 UIntPtr。
然而,在 C#/mono 中,long 始终定义为 Int64。
现在使用 IntPtr 有点不方便。 是否有任何我可以应用的 MarshalAs 属性,或者我可以编写的自定义封送拆收器,以便我实际上可以在结构中拥有 ulong ,但它本机映射到 IntPtr ?这样相同的代码就可以在 x86-32 和 x86-64 上运行。
【问题讨论】:
标签: c# linux mono pinvoke marshalling