ClangSharp icon indicating copy to clipboard operation
ClangSharp copied to clipboard

Support `extern const` and `extern` variables

Open jwosty opened this issue 2 years ago • 0 comments

Would be nice to be able to get bindings for extern global variables. Apple's C APIs contain quite a lot of these; for example:

typedef const struct __CFAllocator * CFAllocatorRef;
extern const CFAllocatorRef kCFAllocatorDefault;
extern const CFAllocatorRef kCFAllocatorMalloc;
// ...etc

Obviously the tricky part is that any binding to this needs dynamic library load calls somewhere; DllImport alone isn't enough.

One possible binding would be:

public partial struct __CFAllocator { }

public static unsafe partial class NativeMethods
{
    public static __CFAllocator* kCFAllocatorDefault =>
        (__CFAllocator*)NativeLibrary.GetExport(NativeLibrary.Load("CoreFoundation"), "kCFAllocatorDefault");
        
    public static __CFAllocator* kCFAllocatorMalloc =>
        (__CFAllocator*)NativeLibrary.GetExport(NativeLibrary.Load("CoreFoundation"), "kCFAllocatorMalloc");
}

Or even better (but presumably more difficult to get right in the code generator):

public partial struct __CFAllocator { }

public static unsafe partial class NativeMethods
{
    private static IntPtr? _CoreFoundationLibraryHandle;
    private static IntPtr? _kCFAllocatorDefault;
    private static IntPtr? _kCFAllocatorMalloc;

    public static IntPtr CoreFoundationLibraryHandle =>
        _CoreFoundationLibraryHandle ??= NativeLibrary.Load("CoreFoundation");

    public static __CFAllocator* kCFAllocatorDefault => (__CFAllocator*)(_kCFAllocatorDefault ??= IntPtr.Zero);
    
    public static __CFAllocator* kCFAllocatorMalloc => (__CFAllocator*)(_kCFAllocatorMalloc ??= IntPtr.Zero);
}

Of course if the variable is not const (e.g. extern int MyGlobalMutableVar;), the symbol really would have to be re-read every time.

jwosty avatar Nov 30 '23 23:11 jwosty