Accessing C++ class method from ObjC++ code

  • Hi

    I have a C++ class definition in a file that looks like this:

    class Vision {

    public: void analyze(NSMutableArray* a);

    };

    The implementation of this class in located in a seperate file (.mm
    extension) and compiled as Obj-C++ code.

    I have an AppController ObjC class that has as an instance variable of
    pointer to a Vision object. The AppController.mm file is also compiled
    as Obj-C++. AppController.mm imports AppController.h which in turns
    imports Vision.h.

    In one of AppController's method, I call this : vision-
    > analyze(newArray);

    Everything compiles fine, except linker says :

      "Vision::analyze(NSMutableArray*)", referenced from:
          -[AppController testAction:] in AppController.o
    ld: symbol(s) not found
    collect2: ld returned 1 exit status

    I have tried to specify the symbol visibility using
    __attribute__((visibility("default"))) but that failed as well.

    What am I missing ?

    Thank you

    Charles

    e
  • Forgot to mention,

    this is running on XCode 3.0 under 10.5.1.

    Charles

    On 18-Nov-07, at 12:21 PM, Charles Hamel wrote:

    > Hi
    >
    > I have a C++ class definition in a file that looks like this:
    >
    > class Vision {
    >
    > public: void analyze(NSMutableArray* a);
    >
    > };
    >
    > The implementation of this class in located in a seperate file (.mm
    > extension) and compiled as Obj-C++ code.
    >
    > I have an AppController ObjC class that has as an instance variable
    > of pointer to a Vision object. The AppController.mm file is also
    > compiled as Obj-C++. AppController.mm imports AppController.h which
    > in turns imports Vision.h.
    >
    > In one of AppController's method, I call this : vision-
    >> analyze(newArray);
    >
    > Everything compiles fine, except linker says :
    >
    > "Vision::analyze(NSMutableArray*)", referenced from:
    > -[AppController testAction:] in AppController.o
    > ld: symbol(s) not found
    > collect2: ld returned 1 exit status
    >
    > I have tried to specify the symbol visibility using
    > __attribute__((visibility("default"))) but that failed as well.
    >
    > What am I missing ?
    >
    > Thank you
    >
    > Charles
    >
    > e
  • Are you *sure* that you actually added Vision.mm to your project?

    --
    Scott Ribe
    <scott_ribe...>
    http://www.killerbytes.com/
    (303) 722-0567 voice
  • Yup, it is checked in in the debug and release target.

    On 18-Nov-07, at 12:24 PM, Scott Ribe wrote:

    > Are you *sure* that you actually added Vision.mm to your project?
    >
    > --
    > Scott Ribe
    > <scott_ribe...>
    > http://www.killerbytes.com/
    > (303) 722-0567 voice
    >
    >
  • On Nov 18, 2007 11:27 AM, Charles Hamel <charles...> wrote:
    > Yup, it is checked in in the debug and release target.

    Debug and Release are build configurations, not targets (unless you've
    setup a screwy build system).

    How are you checking that Vision.mm is in a target?
  • Sorry for the confusion

    Get Info on Vision.mm, then Targets Tab, check the box.

    Charles

    On 18-Nov-07, at 1:11 PM, stephen joseph butler wrote:

    > On Nov 18, 2007 11:27 AM, Charles Hamel <charles...> wrote:
    >> Yup, it is checked in in the debug and release target.
    >
    > Debug and Release are build configurations, not targets (unless you've
    > setup a screwy build system).
    >
    > How are you checking that Vision.mm is in a target?
  • On Nov 18, 2007 12:31 PM, Charles Hamel <charles...> wrote:
    > Sorry for the confusion

    n/p

    > Get Info on Vision.mm, then Targets Tab, check the box.

    Okay. Are namespaces involved? Are you sure the function signature
    matches? If your header is this:

    class Vision {
          public: void analyze(NSMutableArray* a);
    };

    Then your implementation needs to be this:

    void Vision::analyze(NSMutableArray* a);

    Basically, your error message is telling us something quite simple.
    The linker can't find the implementation of the function you declared
    in the header. Usually this means one of two things:

    1) The implementation file isn't in the target. But it looks like it is.
    2) The function signature for the implementation doesn't match the declaration.
  • The definition is exactly the same,  I copied/pasted it just to be sure.

    No namespaces involved.

    I understand the nature of the error, it really looks like somehow the
    linker doesn't see the analyze method implementation in Vision.mm,
    even if it is included in the target.

    What I don't get is that AppController.mm compiles fine, it even
    highlights the vision->analyze(...) statement, so it knows it is a
    valid symbol right ?

    I have read the Apple doc many time now and I don't get what's
    missing, is there a way to force the linker with some kind of extern
    statement in my case ?

    Thank you

    Charles

    On 18-Nov-07, at 1:43 PM, stephen joseph butler wrote:

    > On Nov 18, 2007 12:31 PM, Charles Hamel <charles...> wrote:
    >> Sorry for the confusion
    >
    > n/p
    >
    >> Get Info on Vision.mm, then Targets Tab, check the box.
    >
    > Okay. Are namespaces involved? Are you sure the function signature
    > matches? If your header is this:
    >
    > class Vision {
    > public: void analyze(NSMutableArray* a);
    > };
    >
    > Then your implementation needs to be this:
    >
    > void Vision::analyze(NSMutableArray* a);
    >
    > Basically, your error message is telling us something quite simple.
    > The linker can't find the implementation of the function you declared
    > in the header. Usually this means one of two things:
    >
    > 1) The implementation file isn't in the target. But it looks like it
    > is.
    > 2) The function signature for the implementation doesn't match the
    > declaration.
  • On Nov 18, 2007, at 11:50 AM, Charles Hamel wrote:

    > The definition is exactly the same,  I copied/pasted it just to be
    > sure.
    >
    > No namespaces involved.
    >
    > I understand the nature of the error, it really looks like somehow
    > the linker doesn't see the analyze method implementation in
    > Vision.mm, even if it is included in the target.
    >
    > What I don't get is that AppController.mm compiles fine, it even
    > highlights the vision->analyze(...) statement, so it knows it is a
    > valid symbol right ?
    >
    > I have read the Apple doc many time now and I don't get what's
    > missing, is there a way to force the linker with some kind of extern
    > statement in my case ?

    You see the Vision.mm file get compiled in the build log? You sure
    some ifdef isn't preventing it from being compiled in?

    -Shawn
  • On 18/11/2007, Shawn Erickson <shawnce...> wrote:
    >
    > On Nov 18, 2007, at 11:50 AM, Charles Hamel wrote:
    >
    >> The definition is exactly the same,  I copied/pasted it just to be
    >> sure.
    >>
    >> No namespaces involved.
    >>
    >> I understand the nature of the error, it really looks like somehow
    >> the linker doesn't see the analyze method implementation in
    >> Vision.mm, even if it is included in the target.
    >>
    >> What I don't get is that AppController.mm compiles fine, it even
    >> highlights the vision->analyze(...) statement, so it knows it is a
    >> valid symbol right ?
    >>
    >> I have read the Apple doc many time now and I don't get what's
    >> missing, is there a way to force the linker with some kind of extern
    >> statement in my case ?
    >
    > You see the Vision.mm file get compiled in the build log? You sure
    > some ifdef isn't preventing it from being compiled in?
    >
    > -Shawn

    Sorry to interject (Sunday afternoon and all...)

    Have you tried added an #error directive to Vision.mm (that proves
    whether it is being compiled or not).

    Then add the #error directive just before calling your C++ code.  And
    add the #error directive into your C++ code to see if it is getting
    compiled.

    #error WTF?

    Back to Sunday afternoon...

    Cheers,
    -H.
  • On Nov 18, 2007 1:50 PM, Charles Hamel <charles...> wrote:
    > The definition is exactly the same,  I copied/pasted it just to be sure.

    ... and added 'Vision::', right? Many times this trips me up in C++. I
    copy and paste the definition, but forget to add the class scope (and
    then I get errors like you are).

    > I understand the nature of the error, it really looks like somehow the
    > linker doesn't see the analyze method implementation in Vision.mm,
    > even if it is included in the target.

    Do something crazy in the function, like
    "call_method_doesnt_exist();". That way when you get the compile error
    you can be 100% sure the file is being compiled.

    > What I don't get is that AppController.mm compiles fine, it even
    > highlights the vision->analyze(...) statement, so it knows it is a
    > valid symbol right ?

    Right... because it's in the header. But the error isn't from the
    compiler (which would highlight invalid symbols) but from the linker
    (which says the symbol doesn't map to any code).

    > I have read the Apple doc many time now and I don't get what's
    > missing, is there a way to force the linker with some kind of extern
    > statement in my case ?

    No... I'm not even sure what that's supposed to mean. Your class
    definition already says that your function is external... that's the
    whole purpose of class definitions and function prototypes! If the
    linker can't find the implementation in its collection of object files
    and dynamic libraries, then you have another problem.
  • Charles:

    What you have defined is a "member" function.  That is, you can't write

    Vision::analyze(...);

    in your user code, you have to instantiate an instance of the class
    before you can use it, i.e.,

    Vison vis;
    vis.analyze(...);

    or

    Vision* vis = new Vision();
    vis->analyze(...);

    If it is really a "class" member function as in Obj-C or Java, you have
    to preface the definition with the keyword "static,"  like:

    class Vision
    {
      public:

    static void analyze(...);
    };

    Now you can call Vision::analyze(...);

    The keyword "static" makes the function available without requiring an
    instance of the class.  However, if you think about it, the
    "class" (static) function can only manipulate any static member data in
    the class (invocation of function may be done without having ANY
    instances of the class instantiated, so no instance member data would be
    available).

    Jonathan

    On Sun, 2007-11-18 at 12:21 -0500, Charles Hamel wrote:
    > Hi
    >
    > I have a C++ class definition in a file that looks like this:
    >
    > class Vision {
    >
    > public: void analyze(NSMutableArray* a);
    >
    > };
    >
    > The implementation of this class in located in a seperate file (.mm
    > extension) and compiled as Obj-C++ code.
    >
    > I have an AppController ObjC class that has as an instance variable of
    > pointer to a Vision object. The AppController.mm file is also compiled
    > as Obj-C++. AppController.mm imports AppController.h which in turns
    > imports Vision.h.
    >
    > In one of AppController's method, I call this : vision-
    >> analyze(newArray);
    >
    > Everything compiles fine, except linker says :
    >
    > "Vision::analyze(NSMutableArray*)", referenced from:
    > -[AppController testAction:] in AppController.o
    > ld: symbol(s) not found
    > collect2: ld returned 1 exit status
    >
    > I have tried to specify the symbol visibility using
    > __attribute__((visibility("default"))) but that failed as well.
    >
    > What am I missing ?
    >
    > Thank you
    >
    > Charles
    >
    > e
previous month november 2007 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
Go to today