Add API that makes it easier to interoperate with C callbacks

Writing your own custom API notes or module map is still introducing an intermediary between Swift and C that did not previously exist. Given the large universe of possible memory management semantics, it makes much more sense to write a custom C function in your project’s bridging header than to invent an API notes syntax that will only ever cover a subset of possible callback APIs.

1 Like

But do you need to control the codebase to introduce a couple of block based wrappers? I didn't try it myself, but wouldn't this work?

Original block unaware API (not under your control):

// API.h
typedef void (*CallbackWithParam)(void*, int param);
void originalCall(int param, void* refCon, CallbackWithParam callback);

// API.c
void originalCall(int param, void* refCon, CallbackWithParam callback) {
    callback(refCon, param);
}

Your wrapper on top, no need to PR it back, just use locally:

// API-Extra.h
typedef void (^BlockWithParam)(int param);
void newCall(int param, BlockWithParam block);

// API-Extra.c
static void wrapperCallback(void* refCon, int param) {
    BlockWithParam block = (BlockWithParam)refCon;
    block(param);
}

void wrappedCall(int param, BlockWithParam block) {
    originalCall(param, block, wrapperCallback);
}

I don't know block API well enough to see if there's a problem with memory management here or not.

My post is not about Clang Blocks in particular, but about interoperability with C more broadly.

AFAIK APINotes were created for this specific purpose: in order to provide additional information for C headers without modyfying them. Let's look at the example of SwiftGTK. It's the biggest codebase I can think of - that has no connection to Apple.

The GTK and it's dependencies are well documented (or at least well enough in most cases) via a machine readable format (in XML). In theory, we know a lot of more information we could provide to the clang-importer to create a nicer Swift API. Currently, the only option is to generate proactively Swift wrapper for all the code in the header files - which in this case produces 10s of MBs of useless binary (aside from 100Ks lines of code).

I admit that in the case of GTK, just APINotes won't be enough to get us rid of the code generator, but we could think how to reduce the amount of generated code.

My conclusion is, that APINotes won't make C apis more usable on it's own - but it might have the power to greatly reduce the amount of effort needed to create a nice Swift Package for a given library - and since most maintainers do it in their free time, I think making such things easier will benefit the Swift community at large.

4 Likes