private SignatureInfo DoEncodingToSig(string encoding) { SignatureInfo info; lock (ms_lock) { if (!ms_encodedTable.TryGetValue(encoding, out info)) { Class klass = new Class("NSMethodSignature"); IntPtr exception = IntPtr.Zero; IntPtr instance = DirectCalls.Callpp(klass, signatureWithObjCTypes, Marshal.StringToHGlobalAnsi(encoding), ref exception); if (exception != IntPtr.Zero) { CocoaException.Raise(exception); } if (instance == IntPtr.Zero) { throw new InvalidCallException(string.Format("Couldn't find the method signature for {0}", encoding)); } info = new SignatureInfo(instance); ms_encodedTable.Add(encoding, info); klass.release(); } } return(info); }
// Note that if we don't do all of this caching the memory tests fail. private SignatureInfo DoClassSelectorToSig(IntPtr target, IntPtr selector) { SignatureInfo info = null; IntPtr exception = IntPtr.Zero; IntPtr id = DirectCalls.Callp(target, klass, ref exception); if (exception != IntPtr.Zero) { CocoaException.Raise(exception); } lock (ms_lock) { KeyValuePair <IntPtr, IntPtr> key = new KeyValuePair <IntPtr, IntPtr>(id, selector); if (!ms_selectorTable.TryGetValue(key, out info)) { // If target's class is itself then target is a class and we need to use // methodSignatureForSelector to get the class method. Otherwise we'll use // instanceMethodSignatureForSelector to see if the class has an instance // method. If that fails we'll fall back on DoInstanceSelectorToSig to see // if the instance has the method. IntPtr instance; if (id == target) { instance = DirectCalls.Callpp(id, methodSignatureForSelector, selector, ref exception); } else { instance = DirectCalls.Callpp(id, instanceMethodSignatureForSelector, selector, ref exception); } if (exception != IntPtr.Zero) { CocoaException.Raise(exception); } if (instance != IntPtr.Zero) { info = new SignatureInfo(instance); ms_selectorTable.Add(key, info); } } } return(info); }
private SignatureInfo DoInstanceSelectorToSig(IntPtr target, IntPtr selector) { IntPtr exception = IntPtr.Zero; IntPtr instance = DirectCalls.Callpp(target, methodSignatureForSelector, selector, ref exception); if (exception != IntPtr.Zero) { CocoaException.Raise(exception); } if (instance == IntPtr.Zero) { string cn = new NSObject(target).class_().Name; string sn = new Selector(selector).Name; throw new InvalidCallException(string.Format("Couldn't find the method signature for {0} {1}", cn, sn)); } return(new SignatureInfo(instance)); }