Using a C undefined struct from Swift

As I'm working on creating a Swift library for SDL, I’m running into a new issue. The C header file declares

typedef struct SDL_Window SDL_Window;

with no further definition; SDL_Window is meant to be opaque, and is referred to throughout the API as a pointer SDL_Window*.

My modulemap file imports the SDL.h umbrella header. SDL.h includes SDL_video.h, which declares SDL_Window above, as well as (for example) SDL_CreateWindow(). My library code can see SDL_CreateWindow(), but not SDL_Window.

If I include a line like struct SDL_Window {}; in the C API module header file, then Swift is able to make the struct typedef visible.

Am I doing something wrong, or is this a limitation of the C importer? Is there a better way to address it?

Since the type's opaque, Swift imports it as an OpaquePointer. The best you can do is typealias SDLWindow = OpaquePointer, or wrap it in a custom struct for your wrapper APIs.

You don't want to provide an incorrect definition in the C code, since then you have problems if you ever dereference the pointer.

2 Likes

Huh. That seems to drop a lot of helpful type information. Couldn't it have defined a Swift type SDL_Window that behaves like an OpaquePointer, but could only be passed to parameters that take SDL_Window* in the C API? That way I don't pass it accidentally to the wrong API.

Yet another use case for something like Haskell's newtype. Like a type alias, but defines a (wait for it) new distinct type that's incompatible with the original type, but coercible when necessary.

3 Likes

Aggressive changes to the default importing rules are unlikely because of Swift's source-compatibility needs, but it might be reasonable to teach the importer to honor some sort of source annotation, perhaps via the apinotes mechanism (or something similar).

3 Likes

I really like the idea of doing this via apinotes, because it’s controllable by the importer (or the intermediary library).

Yes, it's very sad. Please check the following two threads which also cover the issue:

2 Likes