private void DoGetPropsString(StringBuilder builder) { Class klass = class_(); while (klass != null && (IntPtr)klass != IntPtr.Zero) { int count = 0; IntPtr buffer = class_copyPropertyList((IntPtr)klass, ref count); if (count > 0) { PtrArray ivars = new PtrArray(buffer, count); for (int i = 0; i < count; ++i) { IntPtr name = property_getName(ivars[i]); // property_getAttributes? string s = Marshal.PtrToStringAnsi(name); builder.AppendLine(s); } } Marshal.FreeHGlobal(buffer); klass = klass.BaseClass; } }
private void DoAddMethods(Class klass, List <List <string> > table, bool includePrivate) { int count = 0; IntPtr buffer = class_copyMethodList((IntPtr)klass, ref count); if (count > 0) { PtrArray methods = new PtrArray(buffer, count); for (int i = 0; i < count; ++i) { Selector sel = new Selector(method_getName(methods[i])); if (includePrivate || (sel.Name.Length > 0 && sel.Name[0] != '_')) { List <string> row = new List <string>(); row.Add(sel.Name); IntPtr imp = method_getImplementation(methods[i]); row.Add(imp.ToInt32().ToString("X")); table.Add(row); } } } Marshal.FreeHGlobal(buffer); }
static OpaqueInt getItemAt(PtrArray <OpaqueInt> array, int index) { var dataPtr = Marshal.ReadIntPtr(array.Handle); var data = Marshal.ReadIntPtr(dataPtr, IntPtr.Size * index); return(Opaque.GetInstance <OpaqueInt> (data, Transfer.None)); }
private void DoGetIvarString(StringBuilder builder, bool includePrivate) { Class klass = class_(); while (klass != null && (IntPtr)klass != IntPtr.Zero) { int count = 0; IntPtr buffer = class_copyIvarList((IntPtr)klass, ref count); if (count > 0) { PtrArray ivars = new PtrArray(buffer, count); for (int i = 0; i < count; ++i) { IntPtr name = ivar_getName(ivars[i]); string s = Marshal.PtrToStringAnsi(name); if (includePrivate || (s.Length > 0 && s[0] != '_')) { builder.AppendLine(s); } } } Marshal.FreeHGlobal(buffer); klass = klass.BaseClass; } }
public void TestRemoveRange() { var a = new PtrArray <OpaqueInt> (); a.Add(_(1)); a.Add(_(2)); a.Add(_(3)); a.Add(_(4)); a.Add(_(5)); a.Add(_(6)); Assume.That(a.Count, Is.EqualTo(6)); a.RemoveRange(0, 0); Assert.That(a.Count, Is.EqualTo(6)); a.RemoveRange(1, 2); Assert.That(a.Count, Is.EqualTo(4)); Assert.That(getItemAt(a, 0), Is.EqualTo(_(1))); Assert.That(getItemAt(a, 1), Is.EqualTo(_(4))); Assert.That(getItemAt(a, 2), Is.EqualTo(_(5))); Assert.That(getItemAt(a, 3), Is.EqualTo(_(6))); Assert.That(() => a.RemoveRange(-1, 0), Throws.TypeOf <ArgumentOutOfRangeException> ()); Assert.That(() => a.RemoveRange(0, -1), Throws.TypeOf <ArgumentOutOfRangeException> ()); Assert.That(() => a.RemoveRange(3, 4), Throws.TypeOf <ArgumentException> ()); a.Dispose(); Assert.That(() => a.RemoveRange(0, 0), Throws.TypeOf <ObjectDisposedException> ()); Utility.AssertNoGLibLog(); }
// Call imp where args points to buffers containing the arguments and result // is a buffer where the result will be written. public static void Call(IntPtr cif, IntPtr imp, IntPtr result, PtrArray args) { IntPtr exception = IntPtr.Zero; FfiCall(cif, imp, result, args.ToIntPtr(), ref exception); if (exception != IntPtr.Zero) { CocoaException.Raise(exception); } }
public void TestSetSize() { var a = new PtrArray <OpaqueInt> (); Assume.That(a.Count, Is.EqualTo(0)); a.SetSize(5); Assert.That(a.Count, Is.EqualTo(5)); a.Dispose(); Assert.That(() => a.SetSize(0), Throws.TypeOf <ObjectDisposedException> ()); Utility.AssertNoGLibLog(); }
private static IntPtr DoAllocStructFfiType(string sname, string pencoding) { List <IntPtr> fieldTypes = new List <IntPtr>(); int index = 0; while (index < pencoding.Length) { if (pencoding[index] == '{') { int i = pencoding.IndexOf('=', index); int j = pencoding.IndexOf('}', index); string sname2 = pencoding.Substring(index + 1, i - index - 1); string pencoding2 = pencoding.Substring(i + 1, j - i - 1); fieldTypes.Add(DoAllocStructFfiType(sname2, pencoding2)); index = j + 1; } else { char code = DoGetCode(pencoding[index++].ToString()); if (code == '\x0') { throw new InvalidCallException("Can only marshal structs whose fields are primitive types or structs with primitive types and " + sname + " isn't."); } fieldTypes.Add(GetFfiType(code)); } } fieldTypes.Add(IntPtr.Zero); // Note that we don't free these, but that should be OK since // there should only be a limited number of structs we marshal // and it doesn't hurt to cache the ffi_type* anyway. PtrArray ft = new PtrArray(fieldTypes.Count); for (int i = 0; i < ft.Length; ++i) { ft[i] = fieldTypes[i]; } IntPtr result = AllocStructFfiType(ft.ToIntPtr()); return(result); }
// Use ffi_type*'s to create an ffi_cif*. Note that libffi will save the atypes // pointer so we can't free it (and we can't use an IntPtr[] without explicity // saving the array). public static IntPtr AllocCif(IntPtr rtype, PtrArray atypes) { if (atypes[atypes.Length - 1] != IntPtr.Zero) { throw new ArgumentException("atypes should be null terminated"); } IntPtr cif = AllocCif(atypes.Length - 1, rtype, atypes.ToIntPtr()); if (cif.ToInt32() == 1) { throw new ArgumentException("FFI_BAD_TYPEDEF"); } else if (cif.ToInt32() == 2) { throw new ArgumentException("FFI_BAD_ABI"); } return(cif); }
private static IntPtr DoCreateCif(MethodInfo info) { IntPtr resultType = Ffi.GetFfiType(info.ReturnType); ParameterInfo[] parms = info.GetParameters(); int numArgs = parms.Length; PtrArray argTypes = new PtrArray(numArgs + 3); argTypes[0] = Ffi.GetFfiType(typeof(NSObject)); argTypes[1] = Ffi.GetFfiType(typeof(Selector)); for (int i = 0; i < numArgs; ++i) { Type type = parms[i].ParameterType; argTypes[i + 2] = Ffi.GetFfiType(type); } argTypes[numArgs + 2] = IntPtr.Zero; return(Ffi.AllocCif(resultType, argTypes)); // note that we don't want to free argTypes }
public void TestSort() { var a = new PtrArray <OpaqueInt> (); a.Add(_(3)); a.Add(_(1)); a.Add(_(2)); Assume.That(getItemAt(a, 0), Is.EqualTo(_(3))); Assume.That(getItemAt(a, 1), Is.EqualTo(_(1))); Assume.That(getItemAt(a, 2), Is.EqualTo(_(2))); a.Sort((x, y) => x.Value - y.Value); Assert.That(getItemAt(a, 0), Is.EqualTo(_(1))); Assert.That(getItemAt(a, 1), Is.EqualTo(_(2))); Assert.That(getItemAt(a, 2), Is.EqualTo(_(3))); Assert.That(() => a.Sort(null), Throws.TypeOf <ArgumentNullException> ()); a.Dispose(); Assert.That(() => a.Sort((x, y) => 0), Throws.TypeOf <ObjectDisposedException> ()); Utility.AssertNoGLibLog(); }
public StackFrame(MethodSignature sig) { m_returnEncoding = sig.GetReturnEncoding(); IntPtr resultType = Ffi.GetFfiType(m_returnEncoding); m_resultBuffer = Ffi.CreateBuffer(m_returnEncoding); int numArgs = sig.GetNumArgs(); m_argBuffers = new PtrArray(numArgs); m_argTypes = new PtrArray(numArgs + 1); for (int i = 0; i < numArgs; ++i) { string encoding = sig.GetArgEncoding(i); m_argBuffers[i] = Ffi.CreateBuffer(encoding); m_argTypes[i] = Ffi.GetFfiType(encoding); } m_argTypes[numArgs] = IntPtr.Zero; m_cif = Ffi.AllocCif(resultType, m_argTypes); }
public void TestRemoveFast() { var a = new PtrArray <OpaqueInt> (); Assume.That(a.Count, Is.EqualTo(0)); Assert.That(a.RemoveFast(_(0)), Is.False); Assert.That(a.Count, Is.EqualTo(0)); a.Add(_(1)); Assume.That(a.Count, Is.EqualTo(1)); Assert.That(a.RemoveFast(_(0)), Is.False); Assert.That(a.Count, Is.EqualTo(1)); Assert.That(a.RemoveFast(_(1)), Is.True); Assert.That(a.Count, Is.EqualTo(0)); a.Add(_(1)); a.Add(_(2)); a.Add(_(3)); a.Add(_(4)); Assume.That(a.Count, Is.EqualTo(4)); Assert.That(a.RemoveFast(_(0)), Is.False); Assert.That(a.Count, Is.EqualTo(4)); Assert.That(a.RemoveFast(_(2)), Is.True); Assert.That(a.Count, Is.EqualTo(3)); Assert.That(getItemAt(a, 0), Is.EqualTo(_(1))); Assert.That(getItemAt(a, 1), Is.EqualTo(_(4))); Assert.That(getItemAt(a, 2), Is.EqualTo(_(3))); a.Dispose(); Assert.That(() => a.RemoveFast(_(0)), Throws.TypeOf <ObjectDisposedException> ()); Utility.AssertNoGLibLog(); }
internal IntPtr Call(IntPtr dummy, IntPtr resultBuffer, IntPtr argBuffers) { Unused.Value = dummy; IntPtr exception = IntPtr.Zero; try { // Get the this pointer for the method we're calling. PtrArray argArray = new PtrArray(argBuffers, m_signature.GetNumArgs() + 2); NSObject instance = (NSObject)Ffi.DrainBuffer(argArray[0], "@"); // Get the selector for the method that was called. // Get the method arguments. string encoding; object[] args = new object[m_signature.GetNumArgs() - 2]; for (int i = 0; i < args.Length; ++i) { encoding = m_signature.GetArgEncoding(i + 2); if (encoding == "@") { args[i] = (NSObject)Ffi.DrainBuffer(argArray[i + 2], encoding); } else { args[i] = Ffi.DrainBuffer(argArray[i + 2], encoding); } // Native code doesn't distinguish between unsigned short and unichar // so we need to fix things up here. Type ptype = m_info.GetParameters()[i].ParameterType; if (ptype == typeof(char)) { args[i] = (char)(UInt16)args[i]; } else if (ptype != typeof(NSObject) && typeof(NSObject).IsAssignableFrom(ptype)) { IntPtr ip = (IntPtr)(NSObject)args[i]; args[i] = NSObject.Lookup(ip); if (args[i] == null && ip != IntPtr.Zero) { throw new InvalidCallException(string.Format("Couldn't create a {0} when calling {1}. Is {0} registered or exported?", ptype, m_info.Name)); } } // Provide a better error message than the uber lame: "parameters". if (args[i] != null && !ptype.IsAssignableFrom(args[i].GetType())) { throw new InvalidCallException(string.Format("Expected a {0} when calling {1} but have a {2}.", ptype, m_info.Name, args[i].GetType())); } } // Call the method, object value = m_info.Invoke(instance, args); // and marshal the result. encoding = m_signature.GetReturnEncoding(); if (encoding == "c" || encoding == "C" || encoding == "s" || encoding == "S") // per 'man ffi_call' small results must be stuffed into "storage that is sizeof(long) or larger" { int r = Convert.ToInt32(value); Ffi.FillBuffer(resultBuffer, r, "l"); } else if (encoding != "v" && encoding != "Vv") { Ffi.FillBuffer(resultBuffer, value, encoding); } } catch (TargetInvocationException ie) { if (LogException != null) { LogException(ie); } else { DoLogException(ie); } exception = DoCreateNativeException(ie.InnerException); } catch (Exception e) { if (LogException != null) { LogException(e); } else { DoLogException(e); } exception = DoCreateNativeException(e); } return(exception); }