0

I'm trying to lear Swift by playing around with a wrapper to GLFW

GLFW allows to add error callbacks with:

GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);

where

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

I tried googling but many solutions refers to callbacks expecting a final parameter which represents the context.

Context parameter which unfortunately I don't have it here.

This is what seems it should work (although the OP explicitly asked for a case similar to mine, no context parameter):

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()
            ...
        }
    }
}

But it keeps firing:

error: a C function pointer cannot be formed from a closure that captures context

as soon as I try to use observer in the callback, context seems captured

How may I solve?

elect
  • 6,765
  • 10
  • 53
  • 119
  • Do you know which thread the callback takes place on? Is it the same one that is calling the original function? – bscothern Sep 25 '19 at 19:35

1 Answers1

0

Solved by using a global variable

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()
elect
  • 6,765
  • 10
  • 53
  • 119