1

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

pacification
  • 5,838
  • 4
  • 29
  • 51
Saeid
  • 2,261
  • 4
  • 27
  • 59

1 Answers1

1

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

}
Saeid
  • 2,261
  • 4
  • 27
  • 59
  • This solved a problem I've been struggling with for a few days and it's surprisingly straight-forward. Thank you! – David Spry Aug 23 '20 at 10:03
  • @DavidSpry Yw, If you find a answer correct, you can vote for the answer instead of thanking it – Saeid Aug 23 '20 at 10:25