C# 如何从Xamarin iOS调用sysctl?

C# 如何从Xamarin iOS调用sysctl?,c#,ios,xamarin.ios,pinvoke,xamarin,C#,Ios,Xamarin.ios,Pinvoke,Xamarin,我正在绞尽脑汁想如何正确地直接从C#调用sysctlbyname。我读过这本书,我想我所做的非常接近,只是编组有点混乱 [DllImport(MonoTouch.Constants.SystemLibrary)] internal static extern int sysctlbyname( [MarshalAs(UnmanagedType.LPStr)] string property, IntPtr output, IntPtr oldLen, IntPtr newp

我正在绞尽脑汁想如何正确地直接从C#调用
sysctlbyname
。我读过这本书,我想我所做的非常接近,只是编组有点混乱

     [DllImport(MonoTouch.Constants.SystemLibrary)]  
    internal static extern int sysctlbyname( [MarshalAs(UnmanagedType.LPStr)] string property, IntPtr output, IntPtr oldLen, IntPtr newp, uint newlen);

    //only works on sysctls that return strings
    public static string SystemStringInfo(string property)
    {
        GCHandle? lenh = null, valh = null;
        try
        {
            object len = 0L;
            lenh=GCHandle.Alloc(len, GCHandleType.Pinned);

            byte[] val;
            int status = sysctlbyname(property, IntPtr.Zero, GCHandle.ToIntPtr(lenh.Value), IntPtr.Zero, 0); //crash here
            if (status == 0)
            {

                val = new byte[(Int64)len];
                valh=GCHandle.Alloc(val, GCHandleType.Pinned);
                status = sysctlbyname(property, GCHandle.ToIntPtr(valh.Value), GCHandle.ToIntPtr(lenh.Value), IntPtr.Zero, 0);
                if (status == 0)
                {
                    return Encoding.UTF8.GetString(val);
                }
            }
            return null;
        }
        finally
        {
            if (lenh.HasValue)
            {
                lenh.Value.Free();
            }
            if (valh.HasValue)
            {
                valh.Value.Free();
            }
        }
    }
当我给它一个虚假的sysctl属性名,比如“foobar”,它将正确地从
sysctlbyname
(带有
-1
)返回。然而,当我给它取一个合适的名字,比如
kern.osrelease
,它就会碰到那一行,然后冻结和/或崩溃

出了什么问题,我该如何让它工作

我知道它不是“完整的”(我确信newp和newlen仍然需要修改,但我无论如何都不使用它们),但下面是我为最终实现这一点所做的

[DllImport(MonoTouch.Constants.SystemLibrary)]  
internal static extern int sysctlbyname( [MarshalAs(UnmanagedType.LPStr)] string property, byte[] output, ref Int64 oldLen, IntPtr newp, uint newlen);

public static string SystemStringInfo(string property)
{
    GCHandle? lenh = null, valh = null;
    Int64 len = 0L;

    byte[] val;
    int status = sysctlbyname(property, null, ref len, IntPtr.Zero, 0);
    if (status == 0)
    {

        val = new byte[(Int64) len];
        status = sysctlbyname(property, val, ref len, IntPtr.Zero, 0);
        if (status == 0)
        {
            return Encoding.UTF8.GetString(val);
        }
    }
    return null;
}
在这里查看我的答案:。我调用了
sysctlbyname
来获取UIDevice信息