Ben Flynn
Ben Flynn

Reputation: 18912

Forward declaring a C++ class in Objective-C

I am writing an Objective-C class that needs to make function calls on a C++ class instance. I found this suggestion, but if I try it I get an error for having an incomplete definition of type 'struct MyCPlusPlusClass'

struct MyCPlusPlusClass;

typedef struct MyCPlusPlusClass MyCPlusPlusClass;

@interface MyBridgeClass() {
    MyCPlusPlusClass *my_CPlusPlus;
}

...

- (id)initWithMrGame:(MyCPlusPlusClass *)cPlusPlus
{
    self = [super init]; 
    if (self) {
        my_CPlusPlus = cPlusPlusClass;
        my_CPlusPlus->p_favorite_integer = 0; // Compiler error
    }
    return self;
}

The actual definition occurs in a .mm file that's generated by a pre-compiler, just to add another layer of challenge.

How might I get this to work?

EDIT: Interpreting Adam's answer

// in MyCode.h

struct MyCPlusPlusClass;  // Forward declaration, no need for #include/#import

@interface MyBridgeClass() {
    struct MyCPlusPlusClass *my_CPlusPlus;
}


// in MyCode.m
#include MyCode.h


// in BigGenerateFile.mm
class MyCPlusPlusClass;

class MyCPlusPlusClass { ... }

My goal is to be able to use MyCPlusPlusClass in MyCode.m, but I can't include the .mm file because the compiler gets very unhappy. It may be that the way this thing is architected is going to make me go a different route.

Upvotes: 0

Views: 2115

Answers (2)

Adam Rosenfield
Adam Rosenfield

Reputation: 400146

You can't access member variables of incomplete structures/classes. To do so, you need to the full definition. Typically you use forward declarations in header files so that anything that includes that header doesn't pull in lots of unnecessary other header files it won't need, but for source files you usually need the full definitions.

So I'd suggest changing you code to something like this:

// Header file (.h)
struct MyCPlusPlusClass;  // Forward declaration, no need for #include/#import

@interface MyBridgeClass() {
    struct MyCPlusPlusClass *my_CPlusPlus;
}

// Source file (.mm)
#include "MyCPlusPlusClass.h"
...
// Can now access my_CPlusPlus->p_favorite_integer etc.

Upvotes: 6

eq-
eq-

Reputation: 10096

You can do a number of things on an incomplete type, but accessing members of an object of that type is not one of them.

A simple possible solution would be a helper function that's defined somewhere where the complete type is available:

void set_p_favorite_integer(MyCPlusPlusClass*, int);
// ...
set_p_favorite_integer(my_CPlusPlus, 0);

Upvotes: 1

Related Questions