0

I have a unique use case where I am using CoreBluetooth in my C++ application. There are a lot of old tutorials on CoreBluetooth implementation for objective c and my code looks familiar to this. My problem is that after initializing CBCentralManager, centralManagerDidUpdateState is not being called.

wrapper.h file for c++

// this file defines c++ functions to be used in the .mm file
void *get_object();

.h file for objective c

#import "wrapper.h"

@interface MyObject : NSObject <CBCentralManagerDelegate, CBPeripheralDelegate>

@property(strong, nonatomic) CBCentralManager *centralManager;

- (id)init;

- (void)initialize_manager;

@end

.mm file

// declared in wrapper.h, this is a c++ method to return a void pointer to MyObject
void *get_object() {
    void *obj_ptr = [[MyObject alloc] init];
    return obj_ptr;
}

// this is the objective c code
@implementation MyObject

- (id)init {
    self = [super init];
    if (self) {

        // this is where the central manager should be created
        [self initialize_manager];
    }
    return self;
}

- (void)initialize_manager {
    _centralManager = [[CBCentralManager alloc] initWithDelegate:self
                                                               queue:nil
                                                             options:nil];
}

// this should get called immediately after initialize_manager
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
   std::cout << "this never gets called" << std::endl;
   NSLog(@"this never gets called");

.cpp file to test it

void *p = get_object();

Summary of code: In my .cpp file I am calling get_object() which initializes a new MyObject and returns a void pointer to it. When initializing a new MyObject, it calls initialize_manager() which should (but currently doesnt call) call centralManagerDidUpdate.

Previous issue I found of centralManagerDidUpdateState not being called: Their problem was they didn't assign the central manager to an instance variable. However, I did so doesn't seem like that applies to me.

Not sure if this is a problem with objective-c++ not handling delegates properly, or if storing MyObject as a void* pointer messes with some internal magic.

Also maybe it is because my program exits too soon? Every implementation of CoreBluetooth I've seen is used in a ViewController, can I replicate the non terminating aspect of a view controller in C++? Maybe it's something to do with async issues? Would appreciate any pointers!

update 1: I think CoreBluetooth may be sharing the same thread as the main c++ application

sean ng pack
  • 65
  • 1
  • 6
  • You haven't said if you are running a runloop (`CFRunLoopRun()` or similar) on your main thread. If not, you will need to allow the system to handle events somewhere. – pmdj May 11 '20 at 09:16
  • thanks @pmdj, my main thread was not using a runloop causing CoreBluetooth callbacks not to work! – sean ng pack May 11 '20 at 12:38
  • You may be able to use a dispatch queue instead - create a new one and pass it to the CoreBluetooth central manager's `queue:` init parameter. Note that newly created dispatch queues will however run on a non-main thread, so delegate methods must have appropriate synchronisation for data structures shared with the main thread. – pmdj May 11 '20 at 12:41
  • Sweet, I will try using a dispatch queue per your suggestion and report back later what I find – sean ng pack May 11 '20 at 13:07
  • also I have a question on the nuisance of main thread with objective c++, does the int main() entry point in c++ and calling an objective c CFRunLoopRun or NSRunloop share the same main thread? It seems like to me they are running on the same thread, so I should put the objective c runloop on one thread and the c++ loop on another – sean ng pack May 11 '20 at 13:10
  • If you call `CFRunLoopRun()`, that function will just keep running and handle events. The function will only return if you explicitly call `CFRunLoopStop()` from one of the event handlers. So you give up control of your main thread when you call it - I hope that answers the question. – pmdj May 11 '20 at 13:13
  • Okay awesome, I think I got it. Thank you so much! – sean ng pack May 11 '20 at 13:16

1 Answers1

0

Posting this short answer for now, will edit as a get cleaner iterations. The problem is that the objective c library (CoreBluetooth) needed to be run on a different thread than my main application.

stay tuned for code implementation

sean ng pack
  • 65
  • 1
  • 6