13 Replies Latest reply: Apr 10, 2008 10:39 AM by AndrewCapon
AndrewCapon Level 1 Level 1 (30 points)
Hi Guys,

First of all forgive my ignorance I am new to Cocoa and Objective C.

Basically I am trying to get some existing C++ code working with a Cocoa front end using Objective C.

I can access objects in C++ from Objective C but cannot work out how to access Objective C objects from C++.

The C++ classes are defined in standard C++ .h and .cpp files. Do I have to wrap them in .m files?

And tips would be greatly appreciated.

Cheers

Andy

Message was edited by: AndrewCapon
  • etresoft Level 7 Level 7 (26,830 points)
    You have a couple of options. You could use Objective-C++, using .mm files and then you could go back and forth relatively transparently. There are some restrictions between the two types of objects, so don't get too fancy.

    A more traditional option is to provide a pure C interface to your C++ and use that.

    Personally, I always use Objective-C++. I don't really use C++ anymore but I do like declaring variables only when I need them instead at the top of every code block.
  • AndrewCapon Level 1 Level 1 (30 points)
    Hi,

    Thanks for the reply.

    Using just objective c++ is out of the window as this app needs to run on multiple operating systems/windowing systems.

    I am getting there by setting the filetype of .cpp files in the XCode project to sourcecode.cpp.objcpp. This allows the files to be compiles the same as .mm I believe.

    The main problem I have now is finding the define that is the equivalent to _OBJC_ for c++ code, my initial guess of _OBJCPP_ is wrong, any ideas?

    Thanks

    Andy
  • etresoft Level 7 Level 7 (26,830 points)
    AndrewCapon wrote:
    I can access objects in C++ from Objective C but cannot work out how to access Objective C objects from C++.


    Perhaps I should have paid closer attention. You cannot go in this directory. You will have to define a pure C interface using a new .h file. You can use "opaque pointers" like Core Foundation does if you need to pass objects. But anything you do with the objects from C++ will have to use the C functions.
  • AndrewCapon Level 1 Level 1 (30 points)
    Maybe I should have put it better as well as I seem to be able to access what I call "Objective C" objects from c++, maybe I am using the incorrect terminology.

    I have a test cpp file OSCLog.cpp:

    /*
    * OSCLog.cpp
    * OSCLog
    *
    * Created by Andrew Capon on 09/04/2008.
    * Copyright 2008 CAD Ltd. All rights reserved.
    *
    */

    #include "OSCLog.h"

    #ifdef WIN32
    void OSCLog::Start(CADTextView *pTVLog)
    {
    pTVLog->AppendText("Hello World");
    }
    #else
    void OSCLog::Start(NSTextView *pTVLog)
    {
    NSString *logStr = [NSString stringWithFormat:@" hello Textview"];
    NSRange endRange;

    endRange.location = [[pTVLog textStorage] length];
    endRange.length = 0;

    [pTVLog replaceCharactersInRange:endRange withString:logStr];

    endRange.length = [logStr length];

    [pTVLog scrollRangeToVisible:endRange];
    }
    #endif



    In XCode I have set this Filetype to sourcecode.cpp.ocjcpp

    I have a Objective c controller class defined by OSCLogController.h:



    //
    // OSCLogController.h
    // OSCLog
    //
    // Created by Andrew Capon on 04/04/2008.
    // Copyright CAD Ltd All rights reserved.
    //

    #import <Cocoa/Cocoa.h>
    #import "OSCLog.h"

    @interface OSCLogController : NSObject
    {
    // controls on the form
    IBOutlet NSTextField *tfIpAddr;
    IBOutlet NSTextField *tfPort;
    IBOutlet NSTextView *tvLog;

    OSCLog *oscLog;
    }

    // Action to start the logging
    -(IBAction)start:(id)sender;

    @end



    And implemented by OSCLogController.m:


    //
    // OSCLogController.m
    // OSCLog
    //
    // Created by Andrew Capon on 04/04/2008.
    // Copyright 2008 CAD Ltd All rights reserved.
    //

    #import "OSCLogController.h"


    @implementation OSCLogController

    -(id)init
    {
    [super init];
    oscLog = new OSCLog();

    return self;
    }

    -(void)dealloc
    {
    delete oscLog;
    [super dealloc];
    }

    -(IBAction)start:(id)sender
    {
    oscLog->Start(tvLog);
    }

    @end



    The NSTextView tvLog is passed to the cpp code which uses it to append some test text to the TextView.

    This all works and is what I was after as the cpp code is using objective c classes (or what I call objective c classes!).


    As you can see I am just using a WIN32 define to switch between WIN32 and OSX, I am really after a define like _OBJC_ for objective c++ to use as the code needs to support more than just two platforms.


    Cheers

    Andy

    Message was edited by: AndrewCapon

    Message was edited by: AndrewCapon
  • AndrewCapon Level 1 Level 1 (30 points)
    Code formatting seems to have been mucked up, sorry about that
  • Tod Kuykendall Level 4 Level 4 (2,270 points)
    Post your code segments bracketed by { code } markers without the spaces to achieve what you want.


    [self doSomething:withThis];


    =Tod
  • AndrewCapon Level 1 Level 1 (30 points)
    Thanks for that, I have updated the post

    Cheers

    Andy
  • etresoft Level 7 Level 7 (26,830 points)
    AndrewCapon wrote:
    As you can see I am just using a WIN32 define to switch between WIN32 and OSX, I am really after a define like _OBJC_ for objective c++ to use as the code needs to support more than just two platforms.


    I get it now. You've hacked up Xcode to build .cpp files as if they were .mm files.

    Why don't you just use _OBJC_? No one other than Apple really uses objective C. You might try using _OBJC_ along with __cplusplus

    There are some additional Apple-specific definitions documented in this technote
  • AndrewCapon Level 1 Level 1 (30 points)
    HI,

    I tried _OBJC_ it is not defined when compiling objective c++!

    I will have a look at the link, thanks for all your help on this.

    Cheers

    Andy
  • AndrewCapon Level 1 Level 1 (30 points)
    mmm, from your link:

    _OBJC_
    This macro is defined when you compile Objective-C .m files or Objective-C++ .mm files, or when you override the file extension with -ObjC or -ObjC++ flags.

    Ill have another look tomorrow!
  • AndrewCapon Level 1 Level 1 (30 points)
    _OBJC_ works today, myst have mucked up yesterday!

    Decided to use _APPLE_ instead anyway.

    Thanks for all your help

    Andy
  • rearcog Level 1 Level 1 (0 points)
    We are in a similar situation. We designed our software so that a large portion of it would not need any Mac APIs. All of those files compile just fine with the cpp extension. We then followed the Bridge design pattern and created C++ classes for our Mac OS build. These classes are in .mm files and they bridge the Mac OS world to our code that doesn't have Mac API calls. Depending on how your code is set up you may not be able to do this as this will only work for certain kinds of architecture.

    Stephen
  • AndrewCapon Level 1 Level 1 (30 points)
    Hi Stephan,

    I'm just keeping the .cpp files and building them as Objective c++ on OSX using #ifdefs for different platforms. Saves another load of files/inheritance.

    Cheers

    Andy