[DotNet] CoreFoundation Pinvokes (#17505)

Updates the pinvokes in CoreFoundation to have blittable types.
I intentionally did *not* do `CFReadStream` and `CFWriteStream` as the
changes needed for those are may create a breaking API change, so those
should probably be their own PR for closer scrutiny.

Please look closely at CFProxySupport as that was the least
straightforward of the changes.
This commit is contained in:
Steve Hawley 2023-02-10 19:06:29 -05:00 коммит произвёл GitHub
Родитель 6adfba60b1
Коммит 309dbe3be0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 350 добавлений и 6 удалений

Просмотреть файл

@ -55,20 +55,31 @@ namespace CoreFoundation {
// CFMessagePortContext
[StructLayout (LayoutKind.Sequential)]
#if NET
unsafe
#endif
struct ContextProxy {
/* CFIndex */
nint version; // must be 0
public /* void * */ IntPtr info;
#if NET
public delegate* unmanaged<IntPtr, IntPtr> retain;
public delegate* unmanaged<IntPtr, void> release;
public delegate* unmanaged<IntPtr, IntPtr> copyDescription;
#else
public /* CFAllocatorRetainCallBack*/ Func<IntPtr, IntPtr> retain;
public /* CFAllocatorReleaseCallBack*/ Action<IntPtr> release;
public /* CFAllocatorCopyDescriptionCallBack*/ Func<IntPtr, IntPtr> copyDescription;
#endif
}
public delegate NSData CFMessagePortCallBack (int type, NSData data);
#if !NET
delegate /* CFDataRef */ IntPtr CFMessagePortCallBackProxy (/* CFMessagePortRef */ IntPtr messagePort, /* SInt32 */ int type, /* CFDataRef */ IntPtr data, /* void* */ IntPtr info);
delegate void CFMessagePortInvalidationCallBackProxy (/* CFMessagePortRef */ IntPtr messagePort, /* void * */ IntPtr info);
#endif
static Dictionary<IntPtr, CFMessagePortCallBack> outputHandles = new Dictionary<IntPtr, CFMessagePortCallBack> (Runtime.IntPtrEqualityComparer);
@ -76,9 +87,11 @@ namespace CoreFoundation {
static Dictionary<IntPtr, CFMessagePortContext?> messagePortContexts = new Dictionary<IntPtr, CFMessagePortContext?> (Runtime.IntPtrEqualityComparer);
#if !NET
static CFMessagePortCallBackProxy messageOutputCallback = new CFMessagePortCallBackProxy (MessagePortCallback);
static CFMessagePortInvalidationCallBackProxy messageInvalidationCallback = new CFMessagePortInvalidationCallBackProxy (MessagePortInvalidationCallback);
#endif
IntPtr contextHandle;
@ -139,7 +152,13 @@ namespace CoreFoundation {
invalidationHandles.Add (GetCheckedHandle (), value);
}
#if NET
unsafe {
CFMessagePortSetInvalidationCallBack (Handle, &MessagePortInvalidationCallback);
}
#else
CFMessagePortSetInvalidationCallBack (Handle, messageInvalidationCallback);
#endif
}
}
@ -172,8 +191,13 @@ namespace CoreFoundation {
base.Dispose (disposing);
}
#if NET
[DllImport (Constants.CoreFoundationLibrary)]
static unsafe extern /* CFMessagePortRef */ IntPtr CFMessagePortCreateLocal (/* CFAllocatorRef */ IntPtr allocator, /* CFStringRef */ IntPtr name, delegate* unmanaged<IntPtr, int, IntPtr, IntPtr, IntPtr> callout, /* CFMessagePortContext */ ContextProxy* context, [MarshalAs (UnmanagedType.I1)] bool* shouldFreeInfo);
#else
[DllImport (Constants.CoreFoundationLibrary)]
static extern /* CFMessagePortRef */ IntPtr CFMessagePortCreateLocal (/* CFAllocatorRef */ IntPtr allocator, /* CFStringRef */ IntPtr name, CFMessagePortCallBackProxy callout, /* CFMessagePortContext */ ref ContextProxy context, [MarshalAs (UnmanagedType.I1)] ref bool shouldFreeInfo);
#endif
[DllImport (Constants.CoreFoundationLibrary)]
static extern /* CFMessagePortRef */ IntPtr CFMessagePortCreateRemote (/* CFAllocatorRef */ IntPtr allocator, /* CFStringRef */ IntPtr name);
@ -208,8 +232,13 @@ namespace CoreFoundation {
[DllImport (Constants.CoreFoundationLibrary)]
static extern void CFMessagePortSetDispatchQueue (/* CFMessagePortRef */ IntPtr ms, dispatch_queue_t queue);
#if NET
[DllImport (Constants.CoreFoundationLibrary)]
static unsafe extern void CFMessagePortSetInvalidationCallBack (/* CFMessagePortRef */ IntPtr ms, delegate* unmanaged<IntPtr, IntPtr, void> callout);
#else
[DllImport (Constants.CoreFoundationLibrary)]
static extern void CFMessagePortSetInvalidationCallBack (/* CFMessagePortRef */ IntPtr ms, CFMessagePortInvalidationCallBackProxy callout);
#endif
[DllImport (Constants.CoreFoundationLibrary)]
static extern IntPtr CFMessagePortGetInvalidationCallBack (/* CFMessagePortRef */ IntPtr ms);
@ -234,19 +263,37 @@ namespace CoreFoundation {
var shortHandle = GCHandle.Alloc (contextProxy);
if (context is not null) {
#if NET
unsafe {
if (context.Retain is not null)
contextProxy.retain = &RetainProxy;
if (context.Release is not null)
contextProxy.release = &ReleaseProxy;
if (context.CopyDescription is not null)
contextProxy.copyDescription = &CopyDescriptionProxy;
}
#else
if (context.Retain is not null)
contextProxy.retain = RetainProxy;
if (context.Release is not null)
contextProxy.release = ReleaseProxy;
if (context.CopyDescription is not null)
contextProxy.copyDescription = CopyDescriptionProxy;
#endif
contextProxy.info = (IntPtr) shortHandle;
lock (messagePortContexts)
messagePortContexts.Add (contextProxy.info, context);
}
try {
#if NET
IntPtr portHandle;
unsafe {
portHandle = CFMessagePortCreateLocal (allocator.GetHandle (), n, &MessagePortCallback, &contextProxy, &shouldFreeInfo);
}
#else
var portHandle = CFMessagePortCreateLocal (allocator.GetHandle (), n, messageOutputCallback, ref contextProxy, ref shouldFreeInfo);
#endif
// TODO handle should free info
if (portHandle == IntPtr.Zero)
@ -279,7 +326,11 @@ namespace CoreFoundation {
//
// Proxy callbacks
//
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (Func<IntPtr, IntPtr>))]
#endif
static IntPtr RetainProxy (IntPtr info)
{
INativeObject? result = null;
@ -295,7 +346,11 @@ namespace CoreFoundation {
return result.GetHandle ();
}
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (Action<IntPtr>))]
#endif
static void ReleaseProxy (IntPtr info)
{
CFMessagePortContext? context;
@ -307,7 +362,11 @@ namespace CoreFoundation {
context.Release ();
}
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (Func<IntPtr, IntPtr>))]
#endif
static IntPtr CopyDescriptionProxy (IntPtr info)
{
NSString? result = null;
@ -322,7 +381,11 @@ namespace CoreFoundation {
return result.GetHandle ();
}
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (CFMessagePortCallBackProxy))]
#endif
static IntPtr MessagePortCallback (IntPtr local, int msgid, IntPtr data, IntPtr info)
{
CFMessagePortCallBack callback;
@ -341,7 +404,11 @@ namespace CoreFoundation {
}
}
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (CFMessagePortInvalidationCallBackProxy))]
#endif
static void MessagePortInvalidationCallback (IntPtr messagePort, IntPtr info)
{
Action? callback;

Просмотреть файл

@ -126,12 +126,23 @@ namespace CoreFoundation {
lock (listeners) {
if (!listeners.TryGetValue (name, out listenersForName)) {
listenersForName = new List<CFNotificationObserverToken> (1);
#if NET
unsafe {
CFNotificationCenterAddObserver (center: Handle,
observer: Handle,
callback: &NotificationCallback,
name: strHandle,
obj: token.observedObject,
suspensionBehavior: (IntPtr) suspensionBehavior);
}
#else
CFNotificationCenterAddObserver (center: Handle,
observer: Handle,
callback: NotificationCallback,
name: strHandle,
obj: token.observedObject,
suspensionBehavior: (IntPtr) suspensionBehavior);
#endif
} else
listenersForName = new List<CFNotificationObserverToken> (listenersForName);
listenersForName.Add (token);
@ -163,9 +174,15 @@ namespace CoreFoundation {
}
}
#if !NET
delegate void CFNotificationCallback (CFNotificationCenterRef center, IntPtr observer, IntPtr name, IntPtr obj, IntPtr userInfo);
#endif
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (CFNotificationCallback))]
#endif
static void NotificationCallback (CFNotificationCenterRef centerPtr, IntPtr observer, IntPtr name, IntPtr obj, IntPtr userInfo)
{
CFNotificationCenter center;
@ -245,10 +262,17 @@ namespace CoreFoundation {
}
#if NET
[DllImport (Constants.CoreFoundationLibrary)]
static extern unsafe void CFNotificationCenterAddObserver (CFNotificationCenterRef center, IntPtr observer,
delegate* unmanaged<CFNotificationCenterRef, IntPtr, IntPtr, IntPtr, IntPtr, void> callback, IntPtr name, IntPtr obj,
/* CFNotificationSuspensionBehavior */ IntPtr suspensionBehavior);
#else
[DllImport (Constants.CoreFoundationLibrary)]
static extern unsafe void CFNotificationCenterAddObserver (CFNotificationCenterRef center, IntPtr observer,
CFNotificationCallback callback, IntPtr name, IntPtr obj,
/* CFNotificationSuspensionBehavior */ IntPtr suspensionBehavior);
#endif
[DllImport (Constants.CoreFoundationLibrary)]
static extern unsafe void CFNotificationCenterPostNotificationWithOptions (CFNotificationCenterRef center, IntPtr name, IntPtr obj, IntPtr userInfo, int options);

Просмотреть файл

@ -615,9 +615,15 @@ namespace CoreFoundation {
return new CFProxySettings (dict);
}
#if !NET
delegate void CFProxyAutoConfigurationResultCallbackInternal (IntPtr client, IntPtr proxyList, IntPtr error);
// helper delegate to reuse code
#endif
#if NET
unsafe delegate IntPtr CreatePACCFRunLoopSource (delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> cb, ref CFStreamClientContext context);
#else
delegate IntPtr CreatePACCFRunLoopSource (CFProxyAutoConfigurationResultCallbackInternal cb, ref CFStreamClientContext context);
#endif
static CFProxy []? ParseProxies (IntPtr proxyList)
{
@ -659,7 +665,11 @@ namespace CoreFoundation {
}
// callback that will sent the client info
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (CFProxyAutoConfigurationResultCallbackInternal))]
#endif
static void ExecutePacCallback (IntPtr client, IntPtr proxyList, IntPtr error)
{
// grab the required structure and set the data, according apple docs:
@ -705,7 +715,12 @@ namespace CoreFoundation {
var clientContext = new CFStreamClientContext ();
clientContext.Info = pacDataPtr;
#if NET
unsafe {
using (var loopSource = new CFRunLoopSource (factory (&ExecutePacCallback, ref clientContext), false))
#else
using (var loopSource = new CFRunLoopSource (factory (ExecutePacCallback, ref clientContext), false))
#endif
using (var mode = new NSString ("Xamarin.iOS.Proxy")) {
if (cancellationToken.IsCancellationRequested)
@ -723,6 +738,9 @@ namespace CoreFoundation {
// does not raise an error if source is not longer present, so no need to worry
runLoop.RemoveSource (loopSource, mode);
}
#if NET
} // matches the unsafe block
#endif
if (cancellationToken.IsCancellationRequested)
throw new OperationCanceledException ("Operation was cancelled.");
@ -761,7 +779,12 @@ namespace CoreFoundation {
var clientContext = new CFStreamClientContext ();
clientContext.Info = pacDataPtr;
#if NET
unsafe {
using (var loopSource = new CFRunLoopSource (factory (&ExecutePacCallback, ref clientContext), false))
#else
using (var loopSource = new CFRunLoopSource (factory (ExecutePacCallback, ref clientContext), false))
#endif
using (var mode = new NSString ("Xamarin.iOS.Proxy")) {
runLoop.AddSource (loopSource, mode);
runLoop.RunInMode (mode, double.MaxValue, false);
@ -770,6 +793,9 @@ namespace CoreFoundation {
pacCbData = (PACProxyCallbackData) Marshal.PtrToStructure (pacDataPtr, typeof (PACProxyCallbackData))!;
// get data from the struct
outError = pacCbData.Error;
#if NET
} // unsafe
#endif
return pacCbData.ProxyList;
} finally {
if (pacCbData.ProxyListPtr != IntPtr.Zero)
@ -780,12 +806,21 @@ namespace CoreFoundation {
}
}
#if NET
[DllImport (Constants.CFNetworkLibrary)]
extern unsafe static /* CFRunLoopSourceRef __nonnull */ IntPtr CFNetworkExecuteProxyAutoConfigurationScript (
/* CFStringRef __nonnull */ IntPtr proxyAutoConfigurationScript,
/* CFURLRef __nonnull */ IntPtr targetURL,
/* CFProxyAutoConfigurationResultCallback __nonnull */ delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> cb,
/* CFStreamClientContext * __nonnull */ ref CFStreamClientContext clientContext);
#else
[DllImport (Constants.CFNetworkLibrary)]
extern static /* CFRunLoopSourceRef __nonnull */ IntPtr CFNetworkExecuteProxyAutoConfigurationScript (
/* CFStringRef __nonnull */ IntPtr proxyAutoConfigurationScript,
/* CFURLRef __nonnull */ IntPtr targetURL,
/* CFProxyAutoConfigurationResultCallback __nonnull */ CFProxyAutoConfigurationResultCallbackInternal cb,
/* CFStreamClientContext * __nonnull */ ref CFStreamClientContext clientContext);
#endif
public static CFProxy []? ExecuteProxyAutoConfigurationScript (string proxyAutoConfigurationScript, Uri targetUrl, out NSError? outError)
{
@ -798,10 +833,20 @@ namespace CoreFoundation {
using (var pacScript = new NSString (proxyAutoConfigurationScript))
using (var url = new NSUrl (targetUrl.AbsoluteUri)) {
#if NET
CreatePACCFRunLoopSource factory;
unsafe {
factory = delegate (delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> cb, ref CFStreamClientContext context)
{
return CFNetworkExecuteProxyAutoConfigurationScript (pacScript.Handle, url.Handle, cb, ref context);
};
}
#else
CreatePACCFRunLoopSource factory = delegate (CFProxyAutoConfigurationResultCallbackInternal cb, ref CFStreamClientContext context)
{
return CFNetworkExecuteProxyAutoConfigurationScript (pacScript.Handle, url.Handle, cb, ref context);
};
#endif
return ExecutePacCFRunLoopSourceBlocking (factory, out outError);
}
}
@ -816,21 +861,40 @@ namespace CoreFoundation {
using (var pacScript = new NSString (proxyAutoConfigurationScript))
using (var url = new NSUrl (targetUrl.AbsoluteUri)) {
#if NET
CreatePACCFRunLoopSource factory;
unsafe {
factory = delegate (delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> cb, ref CFStreamClientContext context)
{
return CFNetworkExecuteProxyAutoConfigurationScript (pacScript.Handle, url.Handle, cb, ref context);
};
}
#else
CreatePACCFRunLoopSource factory = delegate (CFProxyAutoConfigurationResultCallbackInternal cb, ref CFStreamClientContext context)
{
return CFNetworkExecuteProxyAutoConfigurationScript (pacScript.Handle, url.Handle, cb, ref context);
};
#endif
// use the helper task with a factory for this method
return await ExecutePacCFRunLoopSourceAsync (factory, cancellationToken).ConfigureAwait (false);
}
}
#if NET
[DllImport (Constants.CFNetworkLibrary)]
extern unsafe static /* CFRunLoopSourceRef __nonnull */ IntPtr CFNetworkExecuteProxyAutoConfigurationURL (
/* CFURLRef __nonnull */ IntPtr proxyAutoConfigurationURL,
/* CFURLRef __nonnull */ IntPtr targetURL,
/* CFProxyAutoConfigurationResultCallback __nonnull */ delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> cb,
/* CFStreamClientContext * __nonnull */ ref CFStreamClientContext clientContext);
#else
[DllImport (Constants.CFNetworkLibrary)]
extern static /* CFRunLoopSourceRef __nonnull */ IntPtr CFNetworkExecuteProxyAutoConfigurationURL (
/* CFURLRef __nonnull */ IntPtr proxyAutoConfigurationURL,
/* CFURLRef __nonnull */ IntPtr targetURL,
/* CFProxyAutoConfigurationResultCallback __nonnull */ CFProxyAutoConfigurationResultCallbackInternal cb,
/* CFStreamClientContext * __nonnull */ ref CFStreamClientContext clientContext);
#endif
public static CFProxy []? ExecuteProxyAutoConfigurationUrl (Uri proxyAutoConfigurationUrl, Uri targetUrl, out NSError? outError)
{
@ -843,10 +907,20 @@ namespace CoreFoundation {
using (var pacUrl = new NSUrl (proxyAutoConfigurationUrl.AbsoluteUri)) // toll free bridge to CFUrl
using (var url = new NSUrl (targetUrl.AbsoluteUri)) {
#if NET
CreatePACCFRunLoopSource factory;
unsafe {
factory = delegate (delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> cb, ref CFStreamClientContext context)
{
return CFNetworkExecuteProxyAutoConfigurationURL (pacUrl.Handle, url.Handle, cb, ref context);
};
}
#else
CreatePACCFRunLoopSource factory = delegate (CFProxyAutoConfigurationResultCallbackInternal cb, ref CFStreamClientContext context)
{
return CFNetworkExecuteProxyAutoConfigurationURL (pacUrl.Handle, url.Handle, cb, ref context);
};
#endif
return ExecutePacCFRunLoopSourceBlocking (factory, out outError);
}
}
@ -862,10 +936,20 @@ namespace CoreFoundation {
using (var pacUrl = new NSUrl (proxyAutoConfigurationUrl.AbsoluteUri)) // toll free bridge to CFUrl
using (var url = new NSUrl (targetUrl.AbsoluteUri)) {
#if NET
CreatePACCFRunLoopSource factory;
unsafe {
factory = delegate (delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> cb, ref CFStreamClientContext context)
{
return CFNetworkExecuteProxyAutoConfigurationURL (pacUrl.Handle, url.Handle, cb, ref context);
};
}
#else
CreatePACCFRunLoopSource factory = delegate (CFProxyAutoConfigurationResultCallbackInternal cb, ref CFStreamClientContext context)
{
return CFNetworkExecuteProxyAutoConfigurationURL (pacUrl.Handle, url.Handle, cb, ref context);
};
#endif
// use the helper task with a factory for this method
return await ExecutePacCFRunLoopSourceAsync (factory, cancellationToken).ConfigureAwait (false);
}

Просмотреть файл

@ -326,9 +326,15 @@ namespace CoreFoundation {
base.Dispose (disposing);
}
#if !NET
delegate void CFSocketCallBack (IntPtr s, nuint type, IntPtr address, IntPtr data, IntPtr info);
#endif
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (CFSocketCallBack))]
#endif
static void OnCallback (IntPtr s, nuint type, IntPtr address, IntPtr data, IntPtr info)
{
var socket = GCHandle.FromIntPtr (info).Target as CFSocket;
@ -366,15 +372,29 @@ namespace CoreFoundation {
}
}
#if NET
[DllImport (Constants.CoreFoundationLibrary)]
unsafe extern static IntPtr CFSocketCreate (IntPtr allocator, int /*SInt32*/ family, int /*SInt32*/ type, int /*SInt32*/ proto,
nuint /*CFOptionFlags*/ callBackTypes,
delegate* unmanaged<IntPtr, nuint, IntPtr, IntPtr, IntPtr, void> callout, CFSocketContext* ctx);
#else
[DllImport (Constants.CoreFoundationLibrary)]
unsafe extern static IntPtr CFSocketCreate (IntPtr allocator, int /*SInt32*/ family, int /*SInt32*/ type, int /*SInt32*/ proto,
nuint /*CFOptionFlags*/ callBackTypes,
CFSocketCallBack callout, CFSocketContext* ctx);
#endif
#if NET
[DllImport (Constants.CoreFoundationLibrary)]
unsafe extern static IntPtr CFSocketCreateWithNative (IntPtr allocator, CFSocketNativeHandle sock,
nuint /*CFOptionFlags*/ callBackTypes,
delegate* unmanaged<IntPtr, nuint, IntPtr, IntPtr, IntPtr, void> callout, CFSocketContext* ctx);
#else
[DllImport (Constants.CoreFoundationLibrary)]
unsafe extern static IntPtr CFSocketCreateWithNative (IntPtr allocator, CFSocketNativeHandle sock,
nuint /*CFOptionFlags*/ callBackTypes,
CFSocketCallBack callout, CFSocketContext* ctx);
#endif
[DllImport (Constants.CoreFoundationLibrary)]
extern static IntPtr CFSocketCreateRunLoopSource (IntPtr allocator, IntPtr socket, nint order);
@ -402,30 +422,51 @@ namespace CoreFoundation {
CFSocket (int family, int type, int proto, CFRunLoop loop)
{
unsafe {
#if NET
Initialize (
loop,
(CFSocketContext* ctx) => CFSocketCreate (IntPtr.Zero, family, type, proto, (nuint) (ulong) defaultCallbackTypes, &OnCallback, ctx)
);
#else
Initialize (
loop,
(CFSocketContext* ctx) => CFSocketCreate (IntPtr.Zero, family, type, proto, (nuint) (ulong) defaultCallbackTypes, OnCallback, ctx)
);
#endif
}
}
CFSocket (CFSocketNativeHandle sock)
{
unsafe {
#if NET
Initialize (
CFRunLoop.Current,
(CFSocketContext* ctx) => CFSocketCreateWithNative (IntPtr.Zero, sock, (nuint) (ulong) defaultCallbackTypes, &OnCallback, ctx)
);
#else
Initialize (
CFRunLoop.Current,
(CFSocketContext* ctx) => CFSocketCreateWithNative (IntPtr.Zero, sock, (nuint) (ulong) defaultCallbackTypes, OnCallback, ctx)
);
#endif
}
}
internal CFSocket (CFSocketSignature sig, double timeout)
{
unsafe {
#if NET
Initialize (
CFRunLoop.Current,
(CFSocketContext* ctx) => CFSocketCreateConnectedToSocketSignature (IntPtr.Zero, ref sig, (nuint) (ulong) defaultCallbackTypes, &OnCallback, ctx, timeout)
);
#else
Initialize (
CFRunLoop.Current,
(CFSocketContext* ctx) => CFSocketCreateConnectedToSocketSignature (IntPtr.Zero, ref sig, (nuint) (ulong) defaultCallbackTypes, OnCallback, ctx, timeout)
);
#endif
}
}
@ -453,11 +494,19 @@ namespace CoreFoundation {
}
}
#if NET
[DllImport (Constants.CoreFoundationLibrary)]
unsafe extern static IntPtr CFSocketCreateConnectedToSocketSignature (IntPtr allocator, ref CFSocketSignature signature,
nuint /*CFOptionFlags*/ callBackTypes,
delegate* unmanaged<IntPtr, nuint, IntPtr, IntPtr, IntPtr, void> callout,
CFSocketContext* context, double timeout);
#else
[DllImport (Constants.CoreFoundationLibrary)]
unsafe extern static IntPtr CFSocketCreateConnectedToSocketSignature (IntPtr allocator, ref CFSocketSignature signature,
nuint /*CFOptionFlags*/ callBackTypes,
CFSocketCallBack callout,
CFSocketContext* context, double timeout);
#endif
public static CFSocket CreateConnectedToSocketSignature (AddressFamily family, SocketType type,
ProtocolType proto, IPEndPoint endpoint,

Просмотреть файл

@ -292,8 +292,13 @@ namespace CoreFoundation {
[DllImport (Constants.libcLibrary)]
extern static void dispatch_set_context (IntPtr o, IntPtr ctx);
#if NET
[DllImport (Constants.libcLibrary)]
extern unsafe static void dispatch_apply_f (IntPtr iterations, IntPtr queue, IntPtr ctx, delegate* unmanaged<IntPtr, IntPtr, void> dispatch);
#else
[DllImport (Constants.libcLibrary)]
extern static void dispatch_apply_f (IntPtr iterations, IntPtr queue, IntPtr ctx, dispatch_callback_iterations_t dispatch);
#endif
public IntPtr Context {
get {
@ -354,14 +359,21 @@ namespace CoreFoundation {
//
// Dispatching
//
#if !NET
internal delegate void dispatch_callback_t (IntPtr context);
internal static readonly dispatch_callback_t static_dispatch = static_dispatcher_to_managed;
internal delegate void dispatch_callback_iterations_t (IntPtr context, IntPtr count);
internal static readonly dispatch_callback_iterations_t static_dispatch_iterations = static_dispatcher_iterations_to_managed;
#endif
#if NET
[UnmanagedCallersOnly]
internal static void static_dispatcher_to_managed (IntPtr context)
#else
[MonoPInvokeCallback (typeof (dispatch_callback_t))]
static void static_dispatcher_to_managed (IntPtr context)
#endif
{
GCHandle gch = GCHandle.FromIntPtr (context);
var obj = gch.Target as Tuple<Action, DispatchQueue>;
@ -388,7 +400,11 @@ namespace CoreFoundation {
}
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (dispatch_callback_iterations_t))]
#endif
static void static_dispatcher_iterations_to_managed (IntPtr context, IntPtr count)
{
GCHandle gch = GCHandle.FromIntPtr (context);
@ -415,10 +431,13 @@ namespace CoreFoundation {
}
}
#if !NET
internal static readonly dispatch_callback_t free_gchandle = static_free_gchandle;
[MonoPInvokeCallback (typeof (dispatch_callback_t))]
#else
[UnmanagedCallersOnly]
#endif
static void static_free_gchandle (IntPtr context)
{
GCHandle.FromIntPtr (context).Free ();
@ -428,8 +447,13 @@ namespace CoreFoundation {
{
if (action is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (action));
#if NET
unsafe {
dispatch_async_f (Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), &static_dispatcher_to_managed);
}
#else
dispatch_async_f (Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
#endif
}
public void DispatchAsync (DispatchBlock block)
@ -445,7 +469,13 @@ namespace CoreFoundation {
if (action is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (action));
#if NET
unsafe {
dispatch_sync_f (Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), &static_dispatcher_to_managed);
}
#else
dispatch_sync_f (Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
#endif
}
public void DispatchSync (DispatchBlock block)
@ -461,7 +491,13 @@ namespace CoreFoundation {
if (action is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (action));
#if NET
unsafe {
dispatch_barrier_async_f (Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), &static_dispatcher_to_managed);
}
#else
dispatch_barrier_async_f (Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
#endif
}
public void DispatchBarrierAsync (DispatchBlock block)
@ -477,7 +513,13 @@ namespace CoreFoundation {
if (action is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (action));
#if NET
unsafe {
dispatch_barrier_sync_f (Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), &static_dispatcher_to_managed);
}
#else
dispatch_barrier_sync_f (Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
#endif
}
public void DispatchBarrierSync (DispatchBlock block)
@ -492,8 +534,13 @@ namespace CoreFoundation {
{
if (action is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (action));
#if NET
unsafe {
dispatch_after_f (when.Nanoseconds, Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), &static_dispatcher_to_managed);
}
#else
dispatch_after_f (when.Nanoseconds, Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
#endif
}
public void DispatchAfter (DispatchTime when, DispatchBlock block)
@ -508,12 +555,24 @@ namespace CoreFoundation {
{
if (action is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (action));
#if NET
unsafe {
dispatch_apply_f ((IntPtr) times, Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), &static_dispatcher_iterations_to_managed);
}
#else
dispatch_apply_f ((IntPtr) times, Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch_iterations);
#endif
}
public void SetSpecific (IntPtr key, object context)
{
#if NET
unsafe {
dispatch_queue_set_specific (GetCheckedHandle (), key, (IntPtr) GCHandle.Alloc (context), &static_free_gchandle);
}
#else
dispatch_queue_set_specific (GetCheckedHandle (), key, (IntPtr) GCHandle.Alloc (context), free_gchandle);
#endif
}
public object? GetSpecific (IntPtr key)
@ -587,32 +646,57 @@ namespace CoreFoundation {
[DllImport (Constants.libcLibrary, EntryPoint = "dispatch_queue_create_with_target$V2")]
extern static IntPtr dispatch_queue_create_with_target (IntPtr label, IntPtr attr, IntPtr target);
#if NET
[DllImport (Constants.libcLibrary)]
extern unsafe static void dispatch_async_f (IntPtr queue, IntPtr context, delegate* unmanaged<IntPtr, void> dispatch);
#else
[DllImport (Constants.libcLibrary)]
extern static void dispatch_async_f (IntPtr queue, IntPtr context, dispatch_callback_t dispatch);
#endif
[DllImport (Constants.libcLibrary)]
extern static void dispatch_async (IntPtr queue, IntPtr block);
#if NET
[DllImport (Constants.libcLibrary)]
extern unsafe static void dispatch_sync_f (IntPtr queue, IntPtr context, delegate* unmanaged<IntPtr, void> dispatch);
#else
[DllImport (Constants.libcLibrary)]
extern static void dispatch_sync_f (IntPtr queue, IntPtr context, dispatch_callback_t dispatch);
#endif
[DllImport (Constants.libcLibrary)]
extern static void dispatch_sync (IntPtr queue, IntPtr block);
#if NET
[DllImport (Constants.libcLibrary)]
extern unsafe static void dispatch_barrier_async_f (IntPtr queue, IntPtr context, delegate* unmanaged<IntPtr, void> dispatch);
#else
[DllImport (Constants.libcLibrary)]
extern static void dispatch_barrier_async_f (IntPtr queue, IntPtr context, dispatch_callback_t dispatch);
#endif
[DllImport (Constants.libcLibrary)]
extern static void dispatch_barrier_async (IntPtr queue, IntPtr block);
#if NET
[DllImport (Constants.libcLibrary)]
extern unsafe static void dispatch_barrier_sync_f (IntPtr queue, IntPtr context, delegate* unmanaged<IntPtr, void> dispatch);
#else
[DllImport (Constants.libcLibrary)]
extern static void dispatch_barrier_sync_f (IntPtr queue, IntPtr context, dispatch_callback_t dispatch);
#endif
[DllImport (Constants.libcLibrary)]
extern static void dispatch_barrier_sync (IntPtr queue, IntPtr block);
#if NET
[DllImport (Constants.libcLibrary)]
extern unsafe static void dispatch_after_f (/* dispath_time_t */ ulong time, IntPtr queue, IntPtr context, delegate* unmanaged<IntPtr, void> dispatch);
#else
[DllImport (Constants.libcLibrary)]
extern static void dispatch_after_f (/* dispath_time_t */ ulong time, IntPtr queue, IntPtr context, dispatch_callback_t dispatch);
#endif
[DllImport (Constants.libcLibrary)]
extern static void dispatch_after (/* dispath_time_t */ ulong time, IntPtr queue, IntPtr block);
@ -639,8 +723,13 @@ namespace CoreFoundation {
// this returns a "const char*" so we cannot make a string out of it since it will be freed (and crash)
extern static IntPtr dispatch_queue_get_label (IntPtr queue);
#if NET
[DllImport (Constants.libcLibrary)]
extern unsafe static void dispatch_queue_set_specific (IntPtr queue, /* const void* */ IntPtr key, /* void *_Nullable */ IntPtr context, delegate* unmanaged<IntPtr, void> /* _Nullable */ destructor);
#else
[DllImport (Constants.libcLibrary)]
extern static void dispatch_queue_set_specific (IntPtr queue, /* const void* */ IntPtr key, /* void *_Nullable */ IntPtr context, dispatch_callback_t /* _Nullable */ destructor);
#endif
[DllImport (Constants.libcLibrary)]
extern static IntPtr dispatch_queue_get_specific (IntPtr queue, /* const void* */ IntPtr key);
@ -915,7 +1004,13 @@ namespace CoreFoundation {
if (action is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (action));
#if NET
unsafe {
dispatch_group_async_f (GetCheckedHandle (), queue.Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, queue)), &DispatchQueue.static_dispatcher_to_managed);
}
#else
dispatch_group_async_f (GetCheckedHandle (), queue.Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, queue)), DispatchQueue.static_dispatch);
#endif
}
public void Notify (DispatchQueue queue, DispatchBlock block)
@ -933,8 +1028,13 @@ namespace CoreFoundation {
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (queue));
if (action is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (action));
#if NET
unsafe {
dispatch_group_notify_f (GetCheckedHandle (), queue.Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, queue)), &DispatchQueue.static_dispatcher_to_managed);
}
#else
dispatch_group_notify_f (GetCheckedHandle (), queue.Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, queue)), DispatchQueue.static_dispatch);
#endif
}
public void Enter ()
@ -960,11 +1060,21 @@ namespace CoreFoundation {
[DllImport (Constants.libcLibrary)]
extern static IntPtr dispatch_group_create ();
#if NET
[DllImport (Constants.libcLibrary)]
extern unsafe static void dispatch_group_async_f (IntPtr group, IntPtr queue, IntPtr context, delegate* unmanaged<IntPtr, void> block);
#else
[DllImport (Constants.libcLibrary)]
extern static void dispatch_group_async_f (IntPtr group, IntPtr queue, IntPtr context, DispatchQueue.dispatch_callback_t block);
#endif
#if NET
[DllImport (Constants.libcLibrary)]
extern unsafe static void dispatch_group_notify_f (IntPtr group, IntPtr queue, IntPtr context, delegate* unmanaged<IntPtr, void> block);
#else
[DllImport (Constants.libcLibrary)]
extern static void dispatch_group_notify_f (IntPtr group, IntPtr queue, IntPtr context, DispatchQueue.dispatch_callback_t block);
#endif
[DllImport (Constants.libcLibrary)]
extern static void dispatch_group_notify (IntPtr group, IntPtr queue, IntPtr block);

Просмотреть файл

@ -74,8 +74,13 @@ namespace CoreFoundation {
os_release (Handle);
}
#if NET
[DllImport (Constants.libSystemLibrary)]
extern static IntPtr os_log_create (IntPtr subsystem, IntPtr category);
#else
[DllImport (Constants.libSystemLibrary)]
extern static IntPtr os_log_create (string subsystem, string category);
#endif
[DllImport (Constants.libSystemLibrary)]
extern static IntPtr os_retain (IntPtr handle);
@ -98,8 +103,13 @@ namespace CoreFoundation {
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (subsystem));
if (category is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (category));
#if NET
using var subsystemPtr = new TransientString (subsystem);
using var categoryPtr = new TransientString (category);
Handle = os_log_create (subsystemPtr, categoryPtr);
#else
Handle = os_log_create (subsystem, category);
#endif
}
public void Log (string message)

Просмотреть файл

@ -41,7 +41,7 @@ namespace Cecil.Tests {
public string Reason;
}
[Ignore ("work in progress - there are 25 failures, mostly due to delegates")]
[Ignore ("work in progress - there are 6 failures, mostly due to delegates")]
[TestCaseSource (typeof (Helper), nameof (Helper.NetPlatformImplementationAssemblyDefinitions))]
public void CheckForNonBlittablePInvokes (AssemblyInfo info)
{