Оборачивание обратных вызовов C (без контекста) в Swift Closures - PullRequest
0 голосов
/ 23 сентября 2019

Я пытаюсь выучить Swift, играя с оболочкой в ​​GLFW

GLFW позволяет добавлять сообщения об ошибках с:

GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);

где

typedef void (* GLFWerrorfun)(int,const char*);

Я пробовал поискать в Google, но многие решения относятся к обратным вызовам, ожидающим конечный параметр, который представляет контекст.

Параметр контекста, которого, к сожалению, у меня здесь нет.

Это то, что , похоже, должно работать (хотя ФП явно запросил случай, похожий на мой,без параметра контекста):

class glfw {
   typealias ErrorFun = (Int, _ description: String) -> Void
   func setErrorCallback(cbFun: ErrorFun) {
        // Void pointer to `self`:
        let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())

        glfwSetErrorCallback { err, desc in

            // Extract pointer to `self` from void pointer:
            let mySelf = Unmanaged<glfw>.fromOpaque(observer).takeUnretainedValue()
            ...
        }
    }
}

Но он продолжает срабатывать:

ошибка: указатель на функцию C не может быть сформирован из замыкания, которое захватывает контекст

как только я пытаюсь использовать observer в обратном вызове, контекст кажется захваченным

Как мне решить?

1 Ответ

0 голосов
/ 26 сентября 2019

Решено с помощью глобальной переменной

public struct glfw {
    static func setErrorCallback(cbFun: @escaping ErrorFun) {
        _g.errorCB = cbFun
        glfwSetErrorCallback { err, desc in
            _g.errorCB!(Error(rawValue: err)!, String(utf8String: desc!)!)
        }        
    }
    var errorCB: ErrorFun?
}
var _g = glfw()
...