Mixing C++ and Obj-C Pointer?


#1

Sorry - I feel this was covered, but…

I have an Obj-C library. I’m making an Obj-C++ class to wrap it, but it feels like I need two headers? A C++ header for the users, and an Obj-C header for the library? The basics are fine, but I need delegates, so I feel like it’s at least two classes too?

Any juce classes that show a basic use of a good pattern to handle this?

Bruce


#2

Sorry - no-one can spare me a quick tip? I understand I need two headers, one for the C++ Juce stuff to use, one for the Obj-C++ main file to use, but I’m sure there’s a best practice?

Bruce


#3

I don’t think it is a matter of not wanting to help. The question itself is pretty broad. The best examples of wrapping Objective C funtionality in C++ are probably Juce itself. iOS and Mac are ObjC native environments and Juce places a wrapper around them.

As a non Juce example, this:

From aiit does something similiar. He wraps the existing iOS image picker in C++.

Best practice probably depends on what you are out to accomplish. Juce is multi-platform, so those practices are geared towards invoking ObjC under a virtualized C++ wrapper. I didn’t look closely at aiit’s wrapper, but I guess he wants to access a platform specific control in a general Juce way for easier and more consistant UI code.

Another case might be ‘I have an obj C library I don’t plan on duplicating the functionality on other platforms’. In that case, best practice might be to, well, just call it (though it would still make sense to add #ifdef JUCE_xxx wrappers around it so that you could duplicate the missing functionality on other platofrms down the road).

Good luck


#4

Thanks for jumping in. I’ll look at that link. I have a whole bunch of Cross platform and Obj-C code, so I’m fine with a lot, but I was hoping for something like:

Make a C header with C/C++ only definitions,

Make an obj-C header that extends it (imports it? This is where I get fuzzy),

Make an Obj-C++ file to implement the whole class.

Or just which/any juce class that follows a useful formula to do that.

Bruce


#5

I’m really struggling to understand your question!

It’s just the context in which you include the header that matters. If you’re planning on including this header in a .m file then, you can’t put any C++ in it. If you’re going to include it in a .cpp then you can’t put any obj-C in it. And if you’re going to include it in a .mm then you can put anything you want in there.


#6

So I need two header files, right?

My simpler question is, how do I decide what to put in the Obj-C++ header file, and what in the C++ only header file?

Should I make one class that handles the needs of obj-C (it’s a delegate etc.) and C++, or make an Obj-C friendly class that calls back to a C++ parent instance?

Does that make more sense?

To fill you in - I have an Objective C++ SDK - the RedPark iOS serial dongle, and I need to use it from my C++ app/s. I suppose raw pointers and casts would let me bodge it, but I think there’s probably an approach that works best with Juce.

Bruce


#7

Personally, I’d publish a header with a C++ interface for it, then implement that wrapper class in a .mm file where you can include their header.


#8

The solution that minimizes both the total number of lines of Objective-C and the number of public Objective-C interfaces is the “best” one. Ideally, the number of public Objective-C interfaces is equal to zero, as Jules suggested.


#9

OK, so one .h file and one .mm? And I would need to define my Obj-C class in the .mm file (so it can be a delegate etc.).

Does that sound right?

(this is the sort of info I was looking for, btw).

Bruce


#10

Here is how I did it. I am sure it can be done easier.

I assume you want to create a cross-plattform class that can be consumed by both c++ and objective-c where parts have a plattform dependend implementation and parts have a plattform independend implementation.

The public C++ interface clients will consume is declared in Resource.h:

class Resources { public: static File ResourcePathFromName(const String& name); };

In a file named Resources_ios.mm implement the ResourcePathFromName method for the iOS plattform using any Objective-C classes from Apples SDKs you need. Include this file in your Xcode project.

In a file named Resources_win32.mm implement ResourcePathFromName for the windows plattform using for example the Windows-API. Include this file in your Visual Studio project.

Common implementation if you have one can be put in a file named Resources.cpp. Include both files, Resources.h and Resources.cpp in your Visual Studio and Xcode project.

Consuming the Resources class in C++ from Visual Studio is easy. We exposed a C++ interface so we can use it by simply including it when needed. Consuming from Objective-C++ with Xcode works the same way. Simply include it where you need the functionality. Objective-C++ are the files ending with .mm . Consuming from Objective-C is not possible. Objective-C are the files ending with .m . .m files can only consume Objective-C or pure C and we created a C++ interface.

Hope that helped a bit.

Patrick


#11

Make that Resources_win32.cpp, sorry about that.

Patrick