Saeid
Saeid

Reputation: 2321

how implement callback from C++ function to Swift

I tried do something in a cpp class and when doing the function return callback to swift.

So i do these things :

  1. Creating this function in callbackClass.cpp

    int callback::run(void (*callback)(int))
     {
         for (unsigned int i = 0; i < 100; i++)
         {
             callback(i);
         }
         return 0;
     }
    
  2. In callbackClass.hpp :

    class callbackClass.hpp
    {
      .
      .
      .
      public:
         int run(void (*callback)(int));
    };
    
    #endif
    
  3. And for header.h‍‍ :

    int callback(void (*callback)(int));
    

It's good until logging callback in Swift side:

func callbackFunc(){

  callback({valueFromCallback in //call cpp function

    print(valueFromCallback) //Works fine

  })
}

But when try to do other stuff like :

func callbackFunc(){

  var value : String!

  callback({valueFromCallback in //call cpp function

    value = String(valueFromCallback) //It has a problem

  })
}

Xcode return this error :

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

I have already seen these questions but did not help:

Swift: Pass data to a closure that captures context

How to cast self to UnsafeMutablePointer<Void> type in swift

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

Upvotes: 1

Views: 885

Answers (1)

Saeid
Saeid

Reputation: 2321

Eventually I realized it possible to pass 'closure' to c++ as argument

So at first I created a Closure in Swift class:

typealias closureCallback = (Int32) -> ()

Then passed it to cpp side :

  1. In header.h‍‍

    int callback(void (^closureCallback)(int));
    
  2. In callbackClass.hpp :

    class callbackClass.hpp
    {
      .
      .
      .
    
      public:
          int run(void (^closureCallback)(int));
    };
    
    #endif
    
  3. And in callbackClass.cpp

    int callback::run(void (^closureCallback)(int))
     {
         for (unsigned int i = 0; i < 100; i++)
         {
             closureCallback(i);
         }
         return 0;
     }
    

At last handle it in Swift :

typealias closureCallback = (Int32) -> ()

func callbackFunc(){

  var value : String!

  let closureValue: closureCallback = {valueFromclosureCallback in
      value = String(valueFromclosureCallback)
   }

    callback(closureValue) //call cpp function

}

Upvotes: 2

Related Questions