Search code examples
c++cocoaobjective-c++nstablecolumn

Can I use a C++ Class Instance as an Objective-C++ id?


In connecting my C++ data model to my Cocoa table column UI, I'm wondering if I can provide the a C++ class instance at the id (identifier) to initWithIdentifier

// what magic needs to occur to create an id from a CPP class?
id someIDMadeFromAClassInstance = a_ptr_to_a_cpp_class_instance;

NSTableColumn *col = [[NSTableColumn alloc] initWithIdentifier:someIDMadeFromAClassInstance"];

The whole point of this is so that when the NSTable's datasource method objectValueForTableColumn gets called, I can retrieve the id and somehow convert if back to a valid C++ class instance:

id columnIdentifer = [aTableColumn identifier];

MyCPPClass* pAValidClass = [someMagicOnTheID columnIdentifer];

pAValidClass->AClassMethod();

I'm guessing there's a more traditional method of doing this, but I wanted to simplify the connection between the Cocoa UI and a pure C++ model.


Solution

  • A C++ object pointer cannot be stored in an id type variable. In Objective-C, id is a pointer to an Objective-C object of unknown type. Since a C++ object is not an Objective-C object, it is not safe to store the pointer to a C++ object in an id.

    The solution is to add a property to your Objective-C class that will store a C++ object pointer. If you must use an id, you could make an Objective-C class that wraps a property that stores the C++ object pointer, for example:

    @interface MyCPPClassWrapper : NSObject
    
    @property (nonatomic, assign) MyCPPClass *myCPPClass;
    
    @end
    
    // ...
    
    MyCPPClassWrapper *wrapper = [[MyCPPClassWrapper alloc] initWithMyCPPClass:myCPPClass];
    
    // Hand wrapper off to your NSTable
    

    Take a look at NSValue as well. It provides a storage mechanism for C-style pointers. For NSValue, you could do something like this:

    NSValue *someIDMadeFromAClassInstance = [NSValue valueWithPointer:a_ptr_to_a_cpp_class_instance];
    
    NSTableColumn *col = [[NSTableColumn alloc] initWithIdentifier:someIDMadeFromAClassInstance"];
    
    // ...
    
    NSValue *columnIdentifer = (NSValue *)[aTableColumn identifier];
    MyCPPClass* pAValidClass = (MyCPPClass *)[columnIdentifer pointerValue];
    pAValidClass->AClassMethod();